Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
wine
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Sam Joan Roque-Worcel
wine
Commits
04211389
Commit
04211389
authored
24 years ago
by
Eric Pouech
Committed by
Alexandre Julliard
24 years ago
Browse files
Options
Downloads
Patches
Plain Diff
Improved stabs loading (now using recursive parsing, required by stabs
generated by latest gcc versions).
parent
52d10c90
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
debugger/stabs.c
+285
-450
285 additions, 450 deletions
debugger/stabs.c
with
285 additions
and
450 deletions
debugger/stabs.c
+
285
−
450
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
)
{
/*
...
...
@@ -274,28 +234,6 @@ DEBUG_FileSubNr2StabEnum(int filenr, int subnr)
return
ret
;
}
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
)
{
...
...
@@ -314,424 +252,325 @@ 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
;
if
(
ndef
==
1
)
return
TRUE
;
ktd
=
(
struct
known_typedef
*
)
DBG_alloc
(
sizeof
(
struct
known_typedef
)
+
(
ndef
-
1
)
*
sizeof
(
struct
datatype
*
));
hash
=
stab_hash
(
name
);
struct
ParseTypedefData
{
char
*
ptr
;
char
buf
[
1024
];
int
idx
;
};
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_ReadTypedef
(
struct
ParseTypedefData
*
ptd
,
const
char
*
typename
,
struct
datatype
**
dt
);
return
TRUE
;
static
int
DEBUG_PTS_ReadID
(
struct
ParseTypedefData
*
ptd
)
{
char
*
first
=
ptd
->
ptr
;
int
len
;
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
;
}
static
int
DEBUG_HandlePreviousTypedef
(
const
char
*
name
,
const
char
*
stab
)
static
int
DEBUG_PTS_ReadNum
(
struct
ParseTypedefData
*
ptd
,
int
*
v
)
{
int
count
;
enum
debug_type
expect
;
int
hash
;
struct
known_typedef
*
ktd
;
char
*
ptr
;
hash
=
stab_hash
(
name
);
for
(
ktd
=
ktd_head
[
hash
];
ktd
;
ktd
=
ktd
->
next
)
if
((
ktd
->
name
[
0
]
==
name
[
0
])
&&
(
strcmp
(
name
,
ktd
->
name
)
==
0
)
)
break
;
char
*
last
;
/*
* Didn't find it. This must be a new one.
*/
if
(
ktd
==
NULL
)
return
FALSE
;
/*
* Examine the stab to make sure it has the same number of definitions.
*/
count
=
0
;
for
(
ptr
=
strchr
(
stab
,
'='
);
ptr
;
ptr
=
strchr
(
ptr
+
1
,
'='
))
{
if
(
count
>=
ktd
->
ndefs
)
return
FALSE
;
*
v
=
strtol
(
ptd
->
ptr
,
&
last
,
10
);
if
(
last
==
ptd
->
ptr
)
return
-
1
;
ptd
->
ptr
=
last
;
return
0
;
}
/*
* 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
++
;
static
int
DEBUG_PTS_ReadTypeReference
(
struct
ParseTypedefData
*
ptd
,
int
*
filenr
,
int
*
subnr
)
{
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
;
}
if
(
ktd
->
ndefs
!=
count
)
return
FALSE
;
/*
* 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
++
];
return
TRUE
;
return
0
;
}
static
int
DEBUG_FreeRegisteredTypedefs
(
void
)
static
int
DEBUG_PTS_ReadRange
(
struct
ParseTypedefData
*
ptd
,
struct
datatype
**
dt
,
int
*
lo
,
int
*
hi
)
{
int
count
;
int
j
;
struct
known_typedef
*
ktd
;
struct
known_typedef
*
next
;
/* 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
;
}
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
;
static
int
inline
DEBUG_PTS_ReadAggregate
(
struct
ParseTypedefData
*
ptd
,
struct
datatype
*
sdt
)
{
int
sz
,
ofs
;
char
*
last
;
struct
datatype
*
adt
;
int
idx
;
int
doadd
;
sz
=
strtol
(
ptd
->
ptr
,
&
last
,
10
);
if
(
last
==
ptd
->
ptr
)
return
-
1
;
ptd
->
ptr
=
last
;
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...
*/
/* 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
(
DEBUG_PTS_ReadTypedef
(
ptd
,
NULL
,
&
adt
)
==
-
1
)
return
-
1
;
if
(
!
adt
)
return
-
1
;
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
;
if
(
doadd
)
DEBUG_AddStructElement
(
sdt
,
ptd
->
buf
+
idx
,
adt
,
ofs
,
sz
);
ptd
->
idx
=
idx
;
}
ptd
->
ptr
++
;
/* ';' */
return
0
;
}
return
TRUE
;
static
int
inline
DEBUG_PTS_ReadEnum
(
struct
ParseTypedefData
*
ptd
,
struct
datatype
*
edt
)
{
int
ofs
;
int
idx
;
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
;
}
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
;
int
lo
,
hi
;
struct
datatype
*
rdt
;
if
(
DEBUG_HandlePreviousTypedef
(
typename
,
ptr
)
)
return
TRUE
;
/* ar<typeinfo_nodef>;<int>;<int>;<typeinfo> */
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
;
/*
* 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.
*/
DEBUG_SetArrayParams
(
adt
,
lo
,
hi
,
rdt
);
return
0
;
}
for
(
c
=
strchr
(
ptr
,
'='
);
c
!=
NULL
;
c
=
strchr
(
c
+
1
,
'='
)
)
{
/*
* Back up until we get to a non-numeric character, to get datatype
*/
struct
datatype
**
dt
=
DEBUG_ReadTypeEnumBackwards
(
c
-
1
);
if
(
ntypes
>=
allocated_types
)
{
allocated_types
+=
64
;
curr_types
=
DBG_realloc
(
curr_types
,
sizeof
(
struct
datatype
*
)
*
allocated_types
);
if
(
!
curr_types
)
return
FALSE
;
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
*/
if
(
DEBUG_PTS_ReadTypeReference
(
ptd
,
&
filenr1
,
&
subnr1
)
==
-
1
)
return
-
1
;
while
(
*
ptd
->
ptr
==
'='
)
{
ptd
->
ptr
++
;
if
(
new_dt
)
{
DEBUG_Printf
(
DBG_CHN_MESG
,
"Bad recursion (1) in typedef
\n
"
);
return
-
1
;
}
switch
(
c
[
1
])
{
case
'*'
:
*
dt
=
DEBUG_NewDataType
(
DT_POINTER
,
NULL
);
curr_types
[
ntypes
++
]
=
*
dt
;
break
;
case
's'
:
case
'u'
:
*
dt
=
DEBUG_NewDataType
(
DT_STRUCT
,
typename
);
curr_types
[
ntypes
++
]
=
*
dt
;
break
;
case
'a'
:
*
dt
=
DEBUG_NewDataType
(
DT_ARRAY
,
NULL
);
curr_types
[
ntypes
++
]
=
*
dt
;
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
;
break
;
case
'x'
:
stab_strcpy
(
element_name
,
sizeof
(
element_name
),
c
+
3
);
*
dt
=
DEBUG_NewDataType
(
DT_STRUCT
,
element_name
);
curr_types
[
ntypes
++
]
=
*
dt
;
break
;
case
'e'
:
*
dt
=
DEBUG_NewDataType
(
DT_ENUM
,
NULL
);
curr_types
[
ntypes
++
]
=
*
dt
;
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
;
/* 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
;
}
typename
=
NULL
;
}
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
);
break
;
/* then the real definitions */
switch
(
*
ptd
->
ptr
++
)
{
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
;
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
'('
:
tc
=
c
+
1
;
dt2
=
DEBUG_ReadTypeEnum
(
&
tc
);
if
(
!*
dt
&&
*
dt2
)
{
*
dt
=
*
dt2
;
}
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
);
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
(
*
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
;
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'
:
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
;
new_dt
=
DEBUG_NewDataType
(
DT_ARRAY
,
NULL
);
if
(
DEBUG_PTS_ReadArray
(
ptd
,
new_dt
)
==
-
1
)
return
-
1
;
break
;
case
'r'
:
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
'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'
:
new_dt
=
DEBUG_NewDataType
(
DT_ENUM
,
NULL
);
if
(
DEBUG_PTS_ReadEnum
(
ptd
,
new_dt
)
==
-
1
)
return
-
1
;
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
++
;
tc
+=
2
;
if
(
*
tc
==
'\0'
)
*
c
=
'\0'
;
else
strcpy
(
c
,
tc
+
1
);
continue
;
}
/*
* 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
);
/* 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
;
}
/* should check typename is the same too */
new_dt
=
dt1
;
}
if
(
failure
)
{
/* 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
;
}
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
(
DEBUG_PTS_ReadAggregate
(
ptd
,
new_dt
)
==
-
1
)
return
-
1
;
break
;
case
'x'
:
switch
(
*
ptd
->
ptr
++
)
{
case
'e'
:
lo
=
DT_ENUM
;
break
;
case
's'
:
case
'u'
:
lo
=
DT_STRUCT
;
break
;
default:
return
-
1
;
}
if
(
*
tc
==
'\0'
)
*
c
=
'\0'
;
else
strcpy
(
c
,
tc
+
1
);
break
;
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_
FIX
ME
,
"Unknown type
(
%c
).
\n
"
,
c
[
1
]
);
return
FALSE
;
DEBUG_Printf
(
DBG_CHN_ME
SG
,
"Unknown type
'
%c
'
\n
"
,
*
ptd
->
ptr
);
return
-
1
;
}
}
/*
* Now register the type so that if we encounter it again, we will know
* what to do.
*/
DEBUG_RegisterTypedef
(
orig_typename
,
curr_types
,
ntypes
);
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
(
!
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
;
}
*
DEBUG_FileSubNr2StabEnum
(
filenr1
,
subnr1
)
=
*
ret_dt
=
new_dt
;
#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
return
0
;
}
static
int
DEBUG_ParseTypedefStab
(
char
*
ptr
,
const
char
*
typename
)
{
struct
ParseTypedefData
ptd
;
struct
datatype
*
dt
;
int
ret
=
-
1
;
/* check for already existing definition */
return
TRUE
;
ptd
.
idx
=
0
;
if
((
ptd
.
ptr
=
strchr
(
ptr
,
':'
)))
{
ptd
.
ptr
++
;
if
(
*
ptd
.
ptr
!=
'('
)
ptd
.
ptr
++
;
ret
=
DEBUG_PTS_ReadTypedef
(
&
ptd
,
typename
,
&
dt
);
}
if
(
ret
==
-
1
||
*
ptd
.
ptr
)
{
DEBUG_Printf
(
DBG_CHN_MESG
,
"failure on %s at %s
\n
"
,
ptr
,
ptd
.
ptr
);
return
FALSE
;
}
return
TRUE
;
}
static
struct
datatype
*
...
...
@@ -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
;
}
...
...
@@ -1439,7 +1274,7 @@ static BOOL DEBUG_WalkList(struct r_debug* dbg_hdr)
struct
link_map
lm
;
Elf32_Ehdr
ehdr
;
char
bufstr
[
256
];
/*
* Now walk the linked list. In all known ELF implementations,
* the dynamic loader maintains this linked list for us. In some
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment