Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
04211389
Commit
04211389
authored
Dec 01, 2000
by
Eric Pouech
Committed by
Alexandre Julliard
Dec 01, 2000
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improved stabs loading (now using recursive parsing, required by stabs
generated by latest gcc versions).
parent
52d10c90
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
259 additions
and
424 deletions
+259
-424
stabs.c
debugger/stabs.c
+259
-424
No files found.
debugger/stabs.c
View file @
04211389
...
...
@@ -81,46 +81,6 @@ struct stab_nlist {
unsigned
long
n_value
;
};
/*
* This is used to keep track of known datatypes so that we don't redefine
* them over and over again. It sucks up lots of memory otherwise.
*/
struct
known_typedef
{
struct
known_typedef
*
next
;
char
*
name
;
int
ndefs
;
struct
datatype
*
types
[
1
];
};
#define NR_STAB_HASH 521
static
struct
known_typedef
*
ktd_head
[
NR_STAB_HASH
]
=
{
NULL
,};
static
struct
datatype
**
curr_types
=
NULL
;
static
int
allocated_types
=
0
;
static
unsigned
int
stab_hash
(
const
char
*
name
)
{
unsigned
int
hash
=
0
;
unsigned
int
tmp
;
const
char
*
p
;
p
=
name
;
while
(
*
p
)
{
hash
=
(
hash
<<
4
)
+
*
p
++
;
if
(
(
tmp
=
(
hash
&
0xf0000000
))
)
{
hash
^=
tmp
>>
24
;
}
hash
&=
~
tmp
;
}
return
hash
%
NR_STAB_HASH
;
}
static
void
stab_strcpy
(
char
*
dest
,
int
sz
,
const
char
*
source
)
{
/*
...
...
@@ -276,28 +236,6 @@ DEBUG_FileSubNr2StabEnum(int filenr, int subnr)
static
struct
datatype
**
DEBUG_ReadTypeEnumBackwards
(
char
*
x
)
{
int
filenr
,
subnr
;
if
(
*
x
==
')'
)
{
while
(
*
x
!=
'('
)
x
--
;
x
++
;
/* '(' */
filenr
=
strtol
(
x
,
&
x
,
10
);
/* <int> */
x
++
;
/* ',' */
subnr
=
strtol
(
x
,
&
x
,
10
);
/* <int> */
x
++
;
/* ')' */
}
else
{
while
((
*
x
>=
'0'
)
&&
(
*
x
<=
'9'
))
x
--
;
filenr
=
0
;
subnr
=
atol
(
x
+
1
);
}
return
DEBUG_FileSubNr2StabEnum
(
filenr
,
subnr
);
}
static
struct
datatype
**
DEBUG_ReadTypeEnum
(
char
**
x
)
{
int
filenr
,
subnr
;
...
...
@@ -314,422 +252,323 @@ DEBUG_ReadTypeEnum(char **x) {
return
DEBUG_FileSubNr2StabEnum
(
filenr
,
subnr
);
}
static
int
DEBUG_RegisterTypedef
(
const
char
*
name
,
struct
datatype
**
types
,
int
ndef
)
{
int
hash
;
struct
known_typedef
*
ktd
;
struct
ParseTypedefData
{
char
*
ptr
;
char
buf
[
1024
];
int
idx
;
};
if
(
ndef
==
1
)
return
TRUE
;
static
int
DEBUG_PTS_ReadTypedef
(
struct
ParseTypedefData
*
ptd
,
const
char
*
typename
,
struct
datatype
**
dt
)
;
ktd
=
(
struct
known_typedef
*
)
DBG_alloc
(
sizeof
(
struct
known_typedef
)
+
(
ndef
-
1
)
*
sizeof
(
struct
datatype
*
));
static
int
DEBUG_PTS_ReadID
(
struct
ParseTypedefData
*
ptd
)
{
char
*
first
=
ptd
->
ptr
;
int
len
;
hash
=
stab_hash
(
name
);
if
((
ptd
->
ptr
=
strchr
(
ptd
->
ptr
,
':'
))
==
NULL
)
return
-
1
;
len
=
ptd
->
ptr
-
first
;
if
(
len
>=
sizeof
(
ptd
->
buf
)
-
ptd
->
idx
)
return
-
1
;
memcpy
(
ptd
->
buf
+
ptd
->
idx
,
first
,
len
);
ptd
->
buf
[
ptd
->
idx
+
len
]
=
'\0'
;
ptd
->
idx
+=
len
+
1
;
ptd
->
ptr
++
;
/* ':' */
return
0
;
}
ktd
->
name
=
DBG_strdup
(
name
);
ktd
->
ndefs
=
ndef
;
memcpy
(
&
ktd
->
types
[
0
],
types
,
ndef
*
sizeof
(
struct
datatype
*
));
ktd
->
next
=
ktd_head
[
hash
];
ktd_head
[
hash
]
=
ktd
;
static
int
DEBUG_PTS_ReadNum
(
struct
ParseTypedefData
*
ptd
,
int
*
v
)
{
char
*
last
;
return
TRUE
;
*
v
=
strtol
(
ptd
->
ptr
,
&
last
,
10
);
if
(
last
==
ptd
->
ptr
)
return
-
1
;
ptd
->
ptr
=
last
;
return
0
;
}
static
int
DEBUG_HandlePreviousTypedef
(
const
char
*
name
,
const
char
*
stab
)
static
int
DEBUG_PTS_ReadTypeReference
(
struct
ParseTypedefData
*
ptd
,
int
*
filenr
,
int
*
subnr
)
{
int
count
;
enum
debug_type
expect
;
int
hash
;
struct
known_typedef
*
ktd
;
char
*
ptr
;
if
(
*
ptd
->
ptr
==
'('
)
{
/* '(' <int> ',' <int> ')' */
ptd
->
ptr
++
;
if
(
DEBUG_PTS_ReadNum
(
ptd
,
filenr
)
==
-
1
)
return
-
1
;
if
(
*
ptd
->
ptr
++
!=
','
)
return
-
1
;
if
(
DEBUG_PTS_ReadNum
(
ptd
,
subnr
)
==
-
1
)
return
-
1
;
if
(
*
ptd
->
ptr
++
!=
')'
)
return
-
1
;
}
else
{
*
filenr
=
0
;
if
(
DEBUG_PTS_ReadNum
(
ptd
,
subnr
)
==
-
1
)
return
-
1
;
}
return
0
;
}
hash
=
stab_hash
(
name
);
static
int
DEBUG_PTS_ReadRange
(
struct
ParseTypedefData
*
ptd
,
struct
datatype
**
dt
,
int
*
lo
,
int
*
hi
)
{
/* type ';' <int> ';' <int> ';' */
if
(
DEBUG_PTS_ReadTypedef
(
ptd
,
NULL
,
dt
)
==
-
1
)
return
-
1
;
if
(
*
ptd
->
ptr
++
!=
';'
)
return
-
1
;
/* ';' */
if
(
DEBUG_PTS_ReadNum
(
ptd
,
lo
)
==
-
1
)
return
-
1
;
if
(
*
ptd
->
ptr
++
!=
';'
)
return
-
1
;
/* ';' */
if
(
DEBUG_PTS_ReadNum
(
ptd
,
hi
)
==
-
1
)
return
-
1
;
if
(
*
ptd
->
ptr
++
!=
';'
)
return
-
1
;
/* ';' */
return
0
;
}
for
(
ktd
=
ktd_head
[
hash
];
ktd
;
ktd
=
ktd
->
next
)
if
((
ktd
->
name
[
0
]
==
name
[
0
])
&&
(
strcmp
(
name
,
ktd
->
name
)
==
0
)
)
break
;
static
int
inline
DEBUG_PTS_ReadAggregate
(
struct
ParseTypedefData
*
ptd
,
struct
datatype
*
sdt
)
{
int
sz
,
ofs
;
char
*
last
;
struct
datatype
*
adt
;
int
idx
;
int
doadd
;
/*
* Didn't find it. This must be a new one.
*/
if
(
ktd
==
NULL
)
return
FALSE
;
sz
=
strtol
(
ptd
->
ptr
,
&
last
,
10
);
if
(
last
==
ptd
->
ptr
)
return
-
1
;
ptd
->
ptr
=
last
;
/*
* Examine the stab to make sure it has the same number of definitions.
doadd
=
DEBUG_SetStructSize
(
sdt
,
sz
);
/* if the structure has already been filled, just redo the parsing
* but don't store results into the struct
* FIXME: there's a quite ugly memory leak in there...
*/
count
=
0
;
for
(
ptr
=
strchr
(
stab
,
'='
);
ptr
;
ptr
=
strchr
(
ptr
+
1
,
'='
))
{
if
(
count
>=
ktd
->
ndefs
)
return
FALSE
;
/*
* Make sure the types of all of the objects is consistent with
* what we have already parsed.
*/
switch
(
ptr
[
1
])
{
case
'*'
:
expect
=
DT_POINTER
;
break
;
case
's'
:
case
'u'
:
expect
=
DT_STRUCT
;
break
;
case
'a'
:
expect
=
DT_ARRAY
;
break
;
case
'('
:
/* it's mainly a ref to another typedef, skip it */
expect
=
-
1
;
break
;
case
'1'
:
case
'r'
:
expect
=
DT_BASIC
;
break
;
case
'x'
:
expect
=
DT_STRUCT
;
break
;
case
'e'
:
expect
=
DT_ENUM
;
break
;
case
'f'
:
expect
=
DT_FUNC
;
break
;
default:
DEBUG_Printf
(
DBG_CHN_FIXME
,
"Unknown type (%c).
\n
"
,
ptr
[
1
]);
return
FALSE
;
}
if
(
expect
!=
-
1
&&
expect
!=
DEBUG_GetType
(
ktd
->
types
[
count
])
)
return
FALSE
;
count
++
;
}
/* Now parse the individual elements of the structure/union. */
while
(
*
ptd
->
ptr
!=
';'
)
{
/* agg_name : type ',' <int:offset> ',' <int:size> */
idx
=
ptd
->
idx
;
if
(
DEBUG_PTS_ReadID
(
ptd
)
==
-
1
)
return
-
1
;
if
(
ktd
->
ndefs
!=
count
)
return
FALSE
;
if
(
DEBUG_PTS_ReadTypedef
(
ptd
,
NULL
,
&
adt
)
==
-
1
)
return
-
1
;
if
(
!
adt
)
return
-
1
;
/*
* Go through, dig out all of the type numbers, and substitute the
* appropriate things.
*/
count
=
0
;
for
(
ptr
=
strchr
(
stab
,
'='
);
ptr
;
ptr
=
strchr
(
ptr
+
1
,
'='
))
*
DEBUG_ReadTypeEnumBackwards
(
ptr
-
1
)
=
ktd
->
types
[
count
++
];
if
(
*
ptd
->
ptr
++
!=
','
)
return
-
1
;
if
(
DEBUG_PTS_ReadNum
(
ptd
,
&
ofs
)
==
-
1
)
return
-
1
;
if
(
*
ptd
->
ptr
++
!=
','
)
return
-
1
;
if
(
DEBUG_PTS_ReadNum
(
ptd
,
&
sz
)
==
-
1
)
return
-
1
;
if
(
*
ptd
->
ptr
++
!=
';'
)
return
-
1
;
return
TRUE
;
if
(
doadd
)
DEBUG_AddStructElement
(
sdt
,
ptd
->
buf
+
idx
,
adt
,
ofs
,
sz
);
ptd
->
idx
=
idx
;
}
ptd
->
ptr
++
;
/* ';' */
return
0
;
}
static
int
DEBUG_FreeRegisteredTypedefs
(
void
)
static
int
inline
DEBUG_PTS_ReadEnum
(
struct
ParseTypedefData
*
ptd
,
struct
datatype
*
edt
)
{
int
count
;
int
j
;
struct
known_typedef
*
ktd
;
struct
known_typedef
*
next
;
int
ofs
;
int
idx
;
count
=
0
;
for
(
j
=
0
;
j
<
NR_STAB_HASH
;
j
++
)
{
for
(
ktd
=
ktd_head
[
j
];
ktd
;
ktd
=
next
)
{
count
++
;
next
=
ktd
->
next
;
DBG_free
(
ktd
->
name
);
DBG_free
(
ktd
);
}
ktd_head
[
j
]
=
NULL
;
while
(
*
ptd
->
ptr
!=
';'
)
{
idx
=
ptd
->
idx
;
if
(
DEBUG_PTS_ReadID
(
ptd
)
==
-
1
)
return
-
1
;
if
(
DEBUG_PTS_ReadNum
(
ptd
,
&
ofs
)
==
-
1
)
return
-
1
;
if
(
*
ptd
->
ptr
++
!=
','
)
return
-
1
;
DEBUG_AddStructElement
(
edt
,
ptd
->
buf
+
idx
,
NULL
,
ofs
,
0
);
ptd
->
idx
=
idx
;
}
return
TRUE
;
ptd
->
ptr
++
;
return
0
;
}
static
int
DEBUG_ParseTypedefStab
(
char
*
ptr
,
const
char
*
typename
)
static
int
inline
DEBUG_PTS_ReadArray
(
struct
ParseTypedefData
*
ptd
,
struct
datatype
*
adt
)
{
int
arrmax
;
int
arrmin
;
char
*
c
;
struct
datatype
*
curr_type
;
struct
datatype
*
datatype
;
char
element_name
[
1024
];
int
ntypes
=
0
,
ntp
;
int
offset
;
const
char
*
orig_typename
;
int
size
;
char
*
tc
;
char
*
tc2
;
int
failure
;
orig_typename
=
typename
;
if
(
DEBUG_HandlePreviousTypedef
(
typename
,
ptr
)
)
return
TRUE
;
int
lo
,
hi
;
struct
datatype
*
rdt
;
/*
* Go from back to front. First we go through and figure out what
* type numbers we need, and register those types. Then we go in
* and fill the details.
*/
/* ar<typeinfo_nodef>;<int>;<int>;<typeinfo> */
for
(
c
=
strchr
(
ptr
,
'='
);
c
!=
NULL
;
c
=
strchr
(
c
+
1
,
'='
)
)
{
/*
* Back up until we get to a non-numeric character, to get datatype
if
(
*
ptd
->
ptr
++
!=
'r'
)
return
-
1
;
/* FIXME: range type is lost, always assume int */
if
(
DEBUG_PTS_ReadRange
(
ptd
,
&
rdt
,
&
lo
,
&
hi
)
==
-
1
)
return
-
1
;
if
(
DEBUG_PTS_ReadTypedef
(
ptd
,
NULL
,
&
rdt
)
==
-
1
)
return
-
1
;
DEBUG_SetArrayParams
(
adt
,
lo
,
hi
,
rdt
);
return
0
;
}
static
int
DEBUG_PTS_ReadTypedef
(
struct
ParseTypedefData
*
ptd
,
const
char
*
typename
,
struct
datatype
**
ret_dt
)
{
int
idx
,
lo
,
hi
;
struct
datatype
*
new_dt
=
NULL
;
/* newly created data type */
struct
datatype
*
ref_dt
;
/* referenced data type (pointer...) */
struct
datatype
*
dt1
;
/* intermediate data type (scope is limited) */
struct
datatype
*
dt2
;
/* intermediate data type: t1=t2=new_dt */
int
filenr1
,
subnr1
;
int
filenr2
=
0
,
subnr2
=
0
;
/* things are a bit complicated because of the way the typedefs are stored inside
* the file (we cannot keep the struct datatype** around, because address can
* change when realloc is done, so we must call over and over
* DEBUG_FileSubNr2StabEnum to keep the correct values around
* (however, keeping struct datatype* is valid
*/
struct
datatype
**
dt
=
DEBUG_ReadTypeEnumBackwards
(
c
-
1
)
;
if
(
DEBUG_PTS_ReadTypeReference
(
ptd
,
&
filenr1
,
&
subnr1
)
==
-
1
)
return
-
1
;
if
(
ntypes
>=
allocated_types
)
{
allocated_types
+=
64
;
curr_types
=
DBG_realloc
(
curr_types
,
sizeof
(
struct
datatype
*
)
*
allocated_types
);
if
(
!
curr_types
)
return
FALSE
;
while
(
*
ptd
->
ptr
==
'='
)
{
ptd
->
ptr
++
;
if
(
new_dt
)
{
DEBUG_Printf
(
DBG_CHN_MESG
,
"Bad recursion (1) in typedef
\n
"
);
return
-
1
;
}
switch
(
c
[
1
])
{
/* first handle attribute if any */
switch
(
*
ptd
->
ptr
)
{
case
'@'
:
if
(
*++
ptd
->
ptr
==
's'
)
{
ptd
->
ptr
++
;
if
(
DEBUG_PTS_ReadNum
(
ptd
,
&
lo
)
==
-
1
)
{
DEBUG_Printf
(
DBG_CHN_MESG
,
"Not an attribute... NIY
\n
"
);
ptd
->
ptr
-=
2
;
return
-
1
;
}
if
(
*
ptd
->
ptr
++
!=
';'
)
return
-
1
;
}
break
;
}
/* then the real definitions */
switch
(
*
ptd
->
ptr
++
)
{
case
'*'
:
*
dt
=
DEBUG_NewDataType
(
DT_POINTER
,
NULL
);
curr_types
[
ntypes
++
]
=
*
dt
;
new_dt
=
DEBUG_NewDataType
(
DT_POINTER
,
NULL
);
if
(
DEBUG_PTS_ReadTypedef
(
ptd
,
NULL
,
&
ref_dt
)
==
-
1
)
return
-
1
;
DEBUG_SetPointerType
(
new_dt
,
ref_dt
);
break
;
case
's'
:
case
'u'
:
*
dt
=
DEBUG_NewDataType
(
DT_STRUCT
,
typename
);
curr_types
[
ntypes
++
]
=
*
dt
;
case
'('
:
ptd
->
ptr
--
;
/* doit a two level by hand, otherwise we'd need a stack */
if
(
filenr2
||
subnr2
)
{
DEBUG_Printf
(
DBG_CHN_MESG
,
"Bad recursion (2) in typedef
\n
"
);
return
-
1
;
}
if
(
DEBUG_PTS_ReadTypeReference
(
ptd
,
&
filenr2
,
&
subnr2
)
==
-
1
)
return
-
1
;
dt1
=
*
DEBUG_FileSubNr2StabEnum
(
filenr1
,
subnr1
);
dt2
=
*
DEBUG_FileSubNr2StabEnum
(
filenr2
,
subnr2
);
if
(
!
dt1
&&
dt2
)
{
new_dt
=
dt2
;
filenr2
=
subnr2
=
0
;
}
else
if
(
!
dt1
&&
!
dt2
)
{
new_dt
=
NULL
;
}
else
{
DEBUG_Printf
(
DBG_CHN_MESG
,
"Unknown condition %08lx %08lx (%s)
\n
"
,
(
unsigned
long
)
dt1
,
(
unsigned
long
)
dt2
,
ptd
->
ptr
);
return
-
1
;
}
break
;
case
'a'
:
*
dt
=
DEBUG_NewDataType
(
DT_ARRAY
,
NULL
);
curr_types
[
ntypes
++
]
=
*
dt
;
new_
dt
=
DEBUG_NewDataType
(
DT_ARRAY
,
NULL
);
if
(
DEBUG_PTS_ReadArray
(
ptd
,
new_dt
)
==
-
1
)
return
-
1
;
break
;
case
'('
:
/* will be handled in next loop,
* just a ref to another type
*/
curr_types
[
ntypes
++
]
=
NULL
;
break
;
case
'1'
:
case
'r'
:
*
dt
=
DEBUG_NewDataType
(
DT_BASIC
,
typename
);
curr_types
[
ntypes
++
]
=
*
dt
;
new_dt
=
DEBUG_NewDataType
(
DT_BASIC
,
typename
);
assert
(
!*
DEBUG_FileSubNr2StabEnum
(
filenr1
,
subnr1
));
*
DEBUG_FileSubNr2StabEnum
(
filenr1
,
subnr1
)
=
new_dt
;
if
(
DEBUG_PTS_ReadRange
(
ptd
,
&
ref_dt
,
&
lo
,
&
hi
)
==
-
1
)
return
-
1
;
/* should perhaps do more here... */
break
;
case
'
x
'
:
stab_strcpy
(
element_name
,
sizeof
(
element_name
),
c
+
3
);
*
dt
=
DEBUG_NewDataType
(
DT_STRUCT
,
element_name
)
;
curr_types
[
ntypes
++
]
=
*
dt
;
case
'
f
'
:
new_dt
=
DEBUG_NewDataType
(
DT_FUNC
,
NULL
);
if
(
DEBUG_PTS_ReadTypedef
(
ptd
,
NULL
,
&
ref_dt
)
==
-
1
)
return
-
1
;
DEBUG_SetPointerType
(
new_dt
,
ref_dt
)
;
break
;
case
'e'
:
*
dt
=
DEBUG_NewDataType
(
DT_ENUM
,
NULL
);
curr_types
[
ntypes
++
]
=
*
dt
;
new_
dt
=
DEBUG_NewDataType
(
DT_ENUM
,
NULL
);
if
(
DEBUG_PTS_ReadEnum
(
ptd
,
new_dt
)
==
-
1
)
return
-
1
;
break
;
case
'f'
:
*
dt
=
DEBUG_NewDataType
(
DT_FUNC
,
NULL
);
curr_types
[
ntypes
++
]
=
*
dt
;
break
;
default:
DEBUG_Printf
(
DBG_CHN_FIXME
,
"Unknown type (%c).
\n
"
,
c
[
1
]);
return
FALSE
;
case
's'
:
case
'u'
:
/* dt1 can have been already defined in a forward definition */
dt1
=
*
DEBUG_FileSubNr2StabEnum
(
filenr1
,
subnr1
);
dt2
=
DEBUG_TypeCast
(
DT_STRUCT
,
typename
);
if
(
!
dt1
)
{
new_dt
=
DEBUG_NewDataType
(
DT_STRUCT
,
typename
);
/* we need to set it here, because a struct can hold a pointer
* to itself
*/
*
DEBUG_FileSubNr2StabEnum
(
filenr1
,
subnr1
)
=
new_dt
;
}
else
{
if
(
DEBUG_GetType
(
dt1
)
!=
DT_STRUCT
)
{
DEBUG_Printf
(
DBG_CHN_MESG
,
"Forward declaration is not an aggregate
\n
"
);
return
-
1
;
}
typename
=
NULL
;
/* should check typename is the same too */
new_dt
=
dt1
;
}
ntp
=
ntypes
-
1
;
/*
* OK, now take a second sweep through. Now we will be digging
* out the definitions of the various components, and storing
* them in the skeletons that we have already allocated. We take
* a right-to left search as this is much easier to parse.
*/
for
(
c
=
strrchr
(
ptr
,
'='
);
c
!=
NULL
;
c
=
strrchr
(
ptr
,
'='
)
)
{
struct
datatype
**
dt
=
DEBUG_ReadTypeEnumBackwards
(
c
-
1
);
struct
datatype
**
dt2
;
curr_type
=
*
dt
;
switch
(
c
[
1
])
{
case
'x'
:
ntp
--
;
tc
=
c
+
3
;
while
(
*
tc
!=
':'
)
tc
++
;
tc
++
;
if
(
*
tc
==
'\0'
)
*
c
=
'\0'
;
else
strcpy
(
c
,
tc
);
if
(
DEBUG_PTS_ReadAggregate
(
ptd
,
new_dt
)
==
-
1
)
return
-
1
;
break
;
case
'*'
:
case
'f'
:
ntp
--
;
tc
=
c
+
2
;
datatype
=
*
DEBUG_ReadTypeEnum
(
&
tc
);
DEBUG_SetPointerType
(
curr_type
,
datatype
);
if
(
*
tc
==
'\0'
)
*
c
=
'\0'
;
else
strcpy
(
c
,
tc
);
break
;
case
'('
:
tc
=
c
+
1
;
dt2
=
DEBUG_ReadTypeEnum
(
&
tc
);
case
'x'
:
switch
(
*
ptd
->
ptr
++
)
{
case
'e'
:
lo
=
DT_ENUM
;
break
;
case
's'
:
case
'u'
:
lo
=
DT_STRUCT
;
break
;
default:
return
-
1
;
}
if
(
!*
dt
&&
*
dt2
)
{
*
dt
=
*
dt2
;
idx
=
ptd
->
idx
;
if
(
DEBUG_PTS_ReadID
(
ptd
)
==
-
1
)
return
-
1
;
new_dt
=
DEBUG_NewDataType
(
lo
,
ptd
->
buf
+
idx
);
ptd
->
idx
=
idx
;
break
;
default:
DEBUG_Printf
(
DBG_CHN_MESG
,
"Unknown type '%c'
\n
"
,
*
ptd
->
ptr
);
return
-
1
;
}
else
if
(
!*
dt
&&
!*
dt2
)
{
/* this should be a basic type, define it */
*
dt2
=
*
dt
=
DEBUG_NewDataType
(
DT_BASIC
,
typename
);
}
else
{
DEBUG_Printf
(
DBG_CHN_MESG
,
"Unknown condition %08lx %08lx (%s)
\n
"
,
(
unsigned
long
)
*
dt
,
(
unsigned
long
)
*
dt2
,
ptr
);
if
((
filenr2
||
subnr2
)
&&
!*
DEBUG_FileSubNr2StabEnum
(
filenr2
,
subnr2
))
{
if
(
!
new_dt
)
{
/* this should be a basic type, define it, or even void */
new_dt
=
DEBUG_NewDataType
(
DT_BASIC
,
typename
);
}
*
DEBUG_FileSubNr2StabEnum
(
filenr2
,
subnr2
)
=
new_dt
;
}
if
(
*
tc
==
'\0'
)
*
c
=
'\0'
;
else
strcpy
(
c
,
tc
);
curr_types
[
ntp
--
]
=
*
dt
;
break
;
case
'1'
:
case
'r'
:
ntp
--
;
/*
* We have already handled these above.
*/
*
c
=
'\0'
;
break
;
case
'a'
:
ntp
--
;
/* ar<typeinfo_nodef>;<int>;<int>;<typeinfo>,<int>,<int>;; */
tc
=
c
+
3
;
/* 'r' */
DEBUG_ReadTypeEnum
(
&
tc
);
tc
++
;
/* ';' */
arrmin
=
strtol
(
tc
,
&
tc
,
10
);
/* <int> */
tc
++
;
/* ';' */
arrmax
=
strtol
(
tc
,
&
tc
,
10
);
/* <int> */
tc
++
;
/* ';' */
datatype
=
*
DEBUG_ReadTypeEnum
(
&
tc
);
/* <typeinfo> */
if
(
*
tc
==
'\0'
)
*
c
=
'\0'
;
else
strcpy
(
c
,
tc
);
DEBUG_SetArrayParams
(
curr_type
,
arrmin
,
arrmax
,
datatype
);
break
;
case
's'
:
case
'u'
:
ntp
--
;
failure
=
0
;
tc
=
c
+
2
;
if
(
DEBUG_SetStructSize
(
curr_type
,
strtol
(
tc
,
&
tc
,
10
))
==
FALSE
)
{
/*
* We have already filled out this structure. Nothing to do,
* so just skip forward to the end of the definition.
*/
while
(
tc
[
0
]
!=
';'
&&
tc
[
1
]
!=
';'
)
tc
++
;
if
(
!
new_dt
)
{
dt1
=
*
DEBUG_FileSubNr2StabEnum
(
filenr1
,
subnr1
);
if
(
!
dt1
)
{
DEBUG_Printf
(
DBG_CHN_MESG
,
"Nothing has been defined <%s>
\n
"
,
ptd
->
ptr
);
return
-
1
;
}
*
ret_dt
=
dt1
;
return
0
;
}
tc
+=
2
;
*
DEBUG_FileSubNr2StabEnum
(
filenr1
,
subnr1
)
=
*
ret_dt
=
new_dt
;
if
(
*
tc
==
'\0'
)
*
c
=
'\0'
;
else
strcpy
(
c
,
tc
+
1
);
continue
;
#if 0
if (typename) {
DEBUG_Printf(DBG_CHN_MESG, "Adding (%d,%d) %s => ", filenr1, subnr1, typename);
DEBUG_PrintTypeCast(new_dt
);
DEBUG_Printf(DBG_CHN_MESG, "\n")
;
}
#endif
/*
* Now parse the individual elements of the structure/union.
*/
while
(
*
tc
!=
';'
)
{
char
*
ti
;
tc2
=
element_name
;
while
(
*
tc
!=
':'
)
*
tc2
++
=
*
tc
++
;
tc
++
;
*
tc2
++
=
'\0'
;
ti
=
tc
;
datatype
=
*
DEBUG_ReadTypeEnum
(
&
tc
);
*
tc
=
'\0'
;
tc
++
;
offset
=
strtol
(
tc
,
&
tc
,
10
);
tc
++
;
size
=
strtol
(
tc
,
&
tc
,
10
);
tc
++
;
if
(
datatype
)
DEBUG_AddStructElement
(
curr_type
,
element_name
,
datatype
,
offset
,
size
);
else
{
failure
=
1
;
/* ... but proceed parsing to the end of the stab */
DEBUG_Printf
(
DBG_CHN_MESG
,
"failure on %s %s
\n
"
,
ptr
,
ti
);
}
}
return
0
;
}
if
(
failure
)
{
static
int
DEBUG_ParseTypedefStab
(
char
*
ptr
,
const
char
*
typename
)
{
struct
ParseTypedefData
ptd
;
struct
datatype
*
dt
;
int
ret
=
-
1
;
/* if we had a undeclared value this one is undeclared too.
* remove it from the stab_types.
* I just set it to NULL to detect bugs in my thoughtprocess.
* FIXME: leaks the memory for the structure elements.
* FIXME: such structures should have been optimized away
* by ld.
*/
*
dt
=
NULL
;
/* check for already existing definition */
ptd
.
idx
=
0
;
if
((
ptd
.
ptr
=
strchr
(
ptr
,
':'
)))
{
ptd
.
ptr
++
;
if
(
*
ptd
.
ptr
!=
'('
)
ptd
.
ptr
++
;
ret
=
DEBUG_PTS_ReadTypedef
(
&
ptd
,
typename
,
&
dt
);
}
if
(
*
tc
==
'\0'
)
*
c
=
'\0'
;
else
strcpy
(
c
,
tc
+
1
);
break
;
case
'e'
:
ntp
--
;
tc
=
c
+
2
;
/*
* Now parse the individual elements of the structure/union.
*/
while
(
*
tc
!=
';'
)
{
tc2
=
element_name
;
while
(
*
tc
!=
':'
)
*
tc2
++
=
*
tc
++
;
tc
++
;
*
tc2
++
=
'\0'
;
offset
=
strtol
(
tc
,
&
tc
,
10
);
tc
++
;
DEBUG_AddStructElement
(
curr_type
,
element_name
,
NULL
,
offset
,
0
);
}
if
(
*
tc
==
'\0'
)
*
c
=
'\0'
;
else
strcpy
(
c
,
tc
+
1
);
break
;
default:
DEBUG_Printf
(
DBG_CHN_FIXME
,
"Unknown type (%c).
\n
"
,
c
[
1
]);
if
(
ret
==
-
1
||
*
ptd
.
ptr
)
{
DEBUG_Printf
(
DBG_CHN_MESG
,
"failure on %s at %s
\n
"
,
ptr
,
ptd
.
ptr
);
return
FALSE
;
}
}
/*
* Now register the type so that if we encounter it again, we will know
* what to do.
*/
DEBUG_RegisterTypedef
(
orig_typename
,
curr_types
,
ntypes
);
return
TRUE
;
}
...
...
@@ -1081,11 +920,7 @@ enum DbgInfoLoad DEBUG_ParseStabs(char * addr, unsigned int load_offset,
#endif
}
DEBUG_FreeRegisteredTypedefs
();
DEBUG_FreeIncludes
();
DBG_free
(
curr_types
);
curr_types
=
NULL
;
allocated_types
=
0
;
return
DIL_LOADED
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment