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
e939206f
Commit
e939206f
authored
Nov 15, 2000
by
Eric Pouech
Committed by
Alexandre Julliard
Nov 15, 2000
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improved internal module handling (module now have a size, map of
loaded module is clearer, better error reporting, seperated module loading code from symbol extraction).
parent
77b2185e
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
697 additions
and
439 deletions
+697
-439
debugger.h
debugger/debugger.h
+43
-33
hash.c
debugger/hash.c
+4
-3
module.c
debugger/module.c
+249
-128
msc.c
debugger/msc.c
+81
-51
stabs.c
debugger/stabs.c
+319
-224
winedbg.c
debugger/winedbg.c
+1
-0
No files found.
debugger/debugger.h
View file @
e939206f
...
...
@@ -26,7 +26,8 @@
#define SYM_TRAMPOLINE 0x10
#define SYM_STEP_THROUGH 0x20
enum
debug_type
{
DT_BASIC
,
DT_CONST
,
DT_POINTER
,
DT_ARRAY
,
DT_STRUCT
,
DT_ENUM
,
DT_TYPEDEF
,
DT_FUNC
,
DT_BITFIELD
};
enum
debug_type
{
DT_BASIC
,
DT_CONST
,
DT_POINTER
,
DT_ARRAY
,
DT_STRUCT
,
DT_ENUM
,
DT_TYPEDEF
,
DT_FUNC
,
DT_BITFIELD
};
/*
...
...
@@ -170,7 +171,8 @@ typedef struct tagDBG_PROCESS {
DBG_THREAD
*
threads
;
int
num_threads
;
unsigned
continue_on_first_exception
;
struct
tagDBG_MODULE
*
modules
;
struct
tagDBG_MODULE
**
modules
;
int
num_modules
;
unsigned
long
dbg_hdr_addr
;
/*
* This is an index we use to keep track of the debug information
...
...
@@ -201,28 +203,22 @@ extern CONTEXT DEBUG_context;
#define DEBUG_WRITE_MEM_VERBOSE(addr, buf, len) \
(DEBUG_WRITE_MEM((addr), (buf), (len)) || (DEBUG_InvalLinAddr( addr ),0))
enum
DbgInfoLoad
{
DIL_DEFERRED
,
DIL_LOADED
,
DIL_NOINFO
,
DIL_ERROR
};
enum
DbgModuleType
{
DMT_UNKNOWN
,
DMT_ELF
,
DMT_NE
,
DMT_PE
};
typedef
struct
tagDBG_MODULE
{
struct
tagDBG_MODULE
*
next
;
void
*
load_addr
;
unsigned
long
size
;
char
*
module_name
;
char
status
;
char
type
;
enum
DbgInfoLoad
dil
;
enum
DbgModuleType
type
;
unsigned
char
main
;
short
int
dbg_index
;
HMODULE
handle
;
void
*
extra_info
;
struct
tagMSC_DBG_INFO
*
msc_info
;
struct
tagELF_DBG_INFO
*
elf_info
;
}
DBG_MODULE
;
/* status field */
#define DM_STATUS_NEW 0
#define DM_STATUS_LOADED 1
#define DM_STATUS_ERROR 2
/* type field */
#define DM_TYPE_UNKNOWN 0
#define DM_TYPE_ELF 1
#define DM_TYPE_NE 2
#define DM_TYPE_PE 3
typedef
struct
{
DWORD
val
;
const
char
*
name
;
...
...
@@ -246,7 +242,8 @@ extern void DEBUG_DelBreakpoint( int num );
extern
void
DEBUG_EnableBreakpoint
(
int
num
,
BOOL
enable
);
extern
void
DEBUG_InfoBreakpoints
(
void
);
extern
BOOL
DEBUG_HandleTrap
(
void
);
extern
BOOL
DEBUG_ShouldContinue
(
DBG_ADDR
*
addr
,
DWORD
code
,
enum
exec_mode
mode
,
int
*
count
);
extern
BOOL
DEBUG_ShouldContinue
(
DBG_ADDR
*
addr
,
DWORD
code
,
enum
exec_mode
mode
,
int
*
count
);
extern
void
DEBUG_SuspendExecution
(
void
);
extern
enum
exec_mode
DEBUG_RestartExecution
(
enum
exec_mode
mode
,
int
count
);
extern
BOOL
DEBUG_IsFctReturn
(
void
);
...
...
@@ -322,7 +319,7 @@ extern int DEBUG_SetSymbolSize(struct name_hash * sym, unsigned int len);
extern
int
DEBUG_SetSymbolBPOff
(
struct
name_hash
*
sym
,
unsigned
int
len
);
extern
int
DEBUG_GetSymbolAddr
(
struct
name_hash
*
sym
,
DBG_ADDR
*
addr
);
extern
int
DEBUG_cmp_sym
(
const
void
*
p1
,
const
void
*
p2
);
extern
BOOL
DEBUG_GetLineNumberAddr
(
struct
name_hash
*
,
const
int
lineno
,
extern
BOOL
DEBUG_GetLineNumberAddr
(
const
struct
name_hash
*
,
const
int
lineno
,
DBG_ADDR
*
addr
,
int
bp_flag
);
extern
int
DEBUG_SetLocalSymbolType
(
struct
wine_locals
*
sym
,
...
...
@@ -331,7 +328,8 @@ extern BOOL DEBUG_Normalize(struct name_hash * nh );
/* debugger/info.c */
extern
void
DEBUG_PrintBasic
(
const
DBG_VALUE
*
value
,
int
count
,
char
format
);
extern
struct
symbol_info
DEBUG_PrintAddress
(
const
DBG_ADDR
*
addr
,
enum
dbg_mode
mode
,
int
flag
);
extern
struct
symbol_info
DEBUG_PrintAddress
(
const
DBG_ADDR
*
addr
,
enum
dbg_mode
mode
,
int
flag
);
extern
void
DEBUG_Help
(
void
);
extern
void
DEBUG_HelpInfo
(
void
);
extern
struct
symbol_info
DEBUG_PrintAddressAndArgs
(
const
DBG_ADDR
*
addr
,
...
...
@@ -370,18 +368,27 @@ extern int DEBUG_IsSelectorSystem( WORD sel );
/* debugger/module.c */
extern
int
DEBUG_LoadEntryPoints
(
const
char
*
prefix
);
extern
void
DEBUG_LoadModule32
(
const
char
*
name
,
HANDLE
hFile
,
DWORD
base
);
extern
DBG_MODULE
*
DEBUG_AddModule
(
const
char
*
name
,
int
type
,
void
*
mod_addr
,
HMODULE
hmod
);
extern
DBG_MODULE
*
DEBUG_FindModuleByName
(
const
char
*
name
,
int
type
);
extern
DBG_MODULE
*
DEBUG_FindModuleByHandle
(
HANDLE
handle
,
int
type
);
extern
DBG_MODULE
*
DEBUG_AddModule
(
const
char
*
name
,
enum
DbgModuleType
type
,
void
*
mod_addr
,
u_long
size
,
HMODULE
hmod
);
extern
DBG_MODULE
*
DEBUG_FindModuleByName
(
const
char
*
name
,
enum
DbgModuleType
type
);
extern
DBG_MODULE
*
DEBUG_FindModuleByHandle
(
HANDLE
handle
,
enum
DbgModuleType
type
);
extern
DBG_MODULE
*
DEBUG_GetProcessMainModule
(
DBG_PROCESS
*
process
);
extern
DBG_MODULE
*
DEBUG_RegisterPEModule
(
HMODULE
,
u_long
load_addr
,
const
char
*
name
);
extern
DBG_MODULE
*
DEBUG_RegisterELFModule
(
u_long
load_addr
,
const
char
*
name
);
extern
DBG_MODULE
*
DEBUG_RegisterPEModule
(
HMODULE
,
u_long
load_addr
,
u_long
size
,
const
char
*
name
);
extern
DBG_MODULE
*
DEBUG_RegisterELFModule
(
u_long
load_addr
,
u_long
size
,
const
char
*
name
);
extern
enum
DbgInfoLoad
DEBUG_RegisterPEDebugInfo
(
DBG_MODULE
*
wmod
,
HANDLE
hFile
,
void
*
_nth
,
unsigned
long
nth_ofs
);
extern
void
DEBUG_ReportDIL
(
enum
DbgInfoLoad
dil
,
const
char
*
pfx
,
const
char
*
filename
,
DWORD
load_addr
);
extern
void
DEBUG_InfoShare
(
void
);
/* debugger/msc.c */
extern
int
DEBUG_RegisterMSCDebugInfo
(
DBG_MODULE
*
module
,
HANDLE
hFile
,
void
*
nth
,
unsigned
long
nth_ofs
);
extern
int
DEBUG_RegisterStabsDebugInfo
(
DBG_MODULE
*
module
,
HANDLE
hFile
,
void
*
nth
,
unsigned
long
nth_ofs
);
extern
enum
DbgInfoLoad
DEBUG_RegisterMSCDebugInfo
(
DBG_MODULE
*
module
,
HANDLE
hFile
,
void
*
nth
,
unsigned
long
nth_ofs
);
extern
enum
DbgInfoLoad
DEBUG_RegisterStabsDebugInfo
(
DBG_MODULE
*
module
,
HANDLE
hFile
,
void
*
nth
,
unsigned
long
nth_ofs
);
extern
void
DEBUG_InitCVDataTypes
(
void
);
/* debugger/registers.c */
...
...
@@ -407,16 +414,18 @@ extern int DEBUG_GetCurrentFrame(struct name_hash ** name,
unsigned
int
*
ebp
);
/* debugger/stabs.c */
extern
int
DEBUG_ReadExecutableDbgInfo
(
const
char
*
exe_name
);
extern
int
DEBUG_ParseStabs
(
char
*
addr
,
unsigned
int
load_offset
,
unsigned
int
staboff
,
int
stablen
,
unsigned
int
strtaboff
,
int
strtablen
);
extern
enum
DbgInfoLoad
DEBUG_ReadExecutableDbgInfo
(
const
char
*
exe_name
);
extern
enum
DbgInfoLoad
DEBUG_ParseStabs
(
char
*
addr
,
unsigned
int
load_offset
,
unsigned
int
staboff
,
int
stablen
,
unsigned
int
strtaboff
,
int
strtablen
);
/* debugger/types.c */
extern
int
DEBUG_nchar
;
extern
void
DEBUG_InitTypes
(
void
);
extern
struct
datatype
*
DEBUG_NewDataType
(
enum
debug_type
xtype
,
const
char
*
typename
);
extern
unsigned
int
DEBUG_TypeDerefPointer
(
const
DBG_VALUE
*
value
,
struct
datatype
**
newtype
);
extern
unsigned
int
DEBUG_TypeDerefPointer
(
const
DBG_VALUE
*
value
,
struct
datatype
**
newtype
);
extern
int
DEBUG_AddStructElement
(
struct
datatype
*
dt
,
char
*
name
,
struct
datatype
*
type
,
int
offset
,
int
size
);
...
...
@@ -429,7 +438,8 @@ extern unsigned int DEBUG_FindStructElement(DBG_VALUE * addr,
const
char
*
ele_name
,
int
*
tmpbuf
);
extern
struct
datatype
*
DEBUG_GetPointerType
(
struct
datatype
*
dt
);
extern
int
DEBUG_GetObjectSize
(
struct
datatype
*
dt
);
extern
unsigned
int
DEBUG_ArrayIndex
(
const
DBG_VALUE
*
addr
,
DBG_VALUE
*
result
,
int
index
);
extern
unsigned
int
DEBUG_ArrayIndex
(
const
DBG_VALUE
*
addr
,
DBG_VALUE
*
result
,
int
index
);
extern
struct
datatype
*
DEBUG_FindOrMakePointerType
(
struct
datatype
*
reftype
);
extern
long
long
int
DEBUG_GetExprValue
(
const
DBG_VALUE
*
addr
,
char
**
format
);
extern
int
DEBUG_SetBitfieldParams
(
struct
datatype
*
dt
,
int
offset
,
...
...
debugger/hash.c
View file @
e939206f
...
...
@@ -203,7 +203,6 @@ DEBUG_AddSymbol( const char * name, const DBG_VALUE *value, const char * source,
name, nh->value.addr.seg, nh->value.addr.off, value->addr.seg, value->addr.off);
#endif
nh
->
value
.
addr
=
value
->
addr
;
if
(
nh
->
value
.
type
==
NULL
&&
value
->
type
!=
NULL
)
{
nh
->
value
.
type
=
value
->
type
;
...
...
@@ -345,7 +344,6 @@ BOOL DEBUG_Normalize(struct name_hash * nh )
BOOL
DEBUG_GetSymbolValue
(
const
char
*
name
,
const
int
lineno
,
DBG_VALUE
*
value
,
int
bp_flag
)
{
char
buffer
[
256
];
struct
name_hash
*
nh
;
for
(
nh
=
name_hash_table
[
name_hash
(
name
)];
nh
;
nh
=
nh
->
next
)
...
...
@@ -360,6 +358,9 @@ BOOL DEBUG_GetSymbolValue( const char * name, const int lineno,
if
(
!
nh
&&
(
name
[
0
]
!=
'_'
))
{
char
buffer
[
256
];
assert
(
strlen
(
name
)
<
sizeof
(
buffer
)
-
2
);
/* one for '_', one for '\0' */
buffer
[
0
]
=
'_'
;
strcpy
(
buffer
+
1
,
name
);
for
(
nh
=
name_hash_table
[
name_hash
(
buffer
)];
nh
;
nh
=
nh
->
next
)
...
...
@@ -393,7 +394,7 @@ BOOL DEBUG_GetSymbolValue( const char * name, const int lineno,
*
* Get the address of a named symbol.
*/
BOOL
DEBUG_GetLineNumberAddr
(
struct
name_hash
*
nh
,
const
int
lineno
,
BOOL
DEBUG_GetLineNumberAddr
(
const
struct
name_hash
*
nh
,
const
int
lineno
,
DBG_ADDR
*
addr
,
int
bp_flag
)
{
int
i
;
...
...
debugger/module.c
View file @
e939206f
...
...
@@ -9,8 +9,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "neexe.h"
#include "file.h"
#include "debugger.h"
#include "toolhelp.h"
#include "wingdi.h"
...
...
@@ -20,8 +18,8 @@
* Creates and links a new module to the current process
*
*/
DBG_MODULE
*
DEBUG_AddModule
(
const
char
*
name
,
int
type
,
void
*
mod_addr
,
HMODULE
hmodule
)
DBG_MODULE
*
DEBUG_AddModule
(
const
char
*
name
,
enum
DbgModuleType
type
,
void
*
mod_addr
,
u_long
size
,
HMODULE
hmodule
)
{
DBG_MODULE
*
wmod
;
...
...
@@ -30,14 +28,18 @@ DBG_MODULE* DEBUG_AddModule(const char* name, int type,
memset
(
wmod
,
0
,
sizeof
(
*
wmod
));
wmod
->
next
=
DEBUG_CurrProcess
->
modules
;
wmod
->
status
=
DM_STATUS_NEW
;
wmod
->
dil
=
DIL_DEFERRED
;
wmod
->
main
=
(
DEBUG_CurrProcess
->
num_modules
==
0
)
;
wmod
->
type
=
type
;
wmod
->
load_addr
=
mod_addr
;
wmod
->
size
=
size
;
wmod
->
handle
=
hmodule
;
wmod
->
dbg_index
=
DEBUG_CurrProcess
->
next_index
;
wmod
->
module_name
=
DBG_strdup
(
name
);
DEBUG_CurrProcess
->
modules
=
wmod
;
DEBUG_CurrProcess
->
modules
=
DBG_realloc
(
DEBUG_CurrProcess
->
modules
,
++
DEBUG_CurrProcess
->
num_modules
*
sizeof
(
DBG_MODULE
*
));
DEBUG_CurrProcess
->
modules
[
DEBUG_CurrProcess
->
num_modules
-
1
]
=
wmod
;
return
wmod
;
}
...
...
@@ -46,15 +48,17 @@ DBG_MODULE* DEBUG_AddModule(const char* name, int type,
* DEBUG_FindModuleByName
*
*/
DBG_MODULE
*
DEBUG_FindModuleByName
(
const
char
*
name
,
int
type
)
DBG_MODULE
*
DEBUG_FindModuleByName
(
const
char
*
name
,
enum
DbgModuleType
type
)
{
DBG_MODULE
*
wmod
;
for
(
wmod
=
DEBUG_CurrProcess
->
modules
;
wmod
;
wmod
=
wmod
->
next
)
{
if
((
type
==
DM_TYPE_UNKNOWN
||
type
==
wmod
->
type
)
&&
!
strcasecmp
(
name
,
wmod
->
module_name
))
break
;
}
return
wmod
;
int
i
;
DBG_MODULE
**
amod
=
DEBUG_CurrProcess
->
modules
;
for
(
i
=
0
;
i
<
DEBUG_CurrProcess
->
num_modules
;
i
++
)
{
if
((
type
==
DMT_UNKNOWN
||
type
==
amod
[
i
]
->
type
)
&&
!
strcasecmp
(
name
,
amod
[
i
]
->
module_name
))
return
amod
[
i
];
}
return
NULL
;
}
/***********************************************************************
...
...
@@ -63,31 +67,35 @@ DBG_MODULE* DEBUG_FindModuleByName(const char* name, int type)
* either the addr where module is loaded, or any address inside the
* module
*/
DBG_MODULE
*
DEBUG_FindModuleByAddr
(
void
*
addr
,
int
type
)
DBG_MODULE
*
DEBUG_FindModuleByAddr
(
void
*
addr
,
enum
DbgModuleType
type
)
{
DBG_MODULE
*
wmod
;
DBG_MODULE
*
res
=
NULL
;
int
i
;
DBG_MODULE
**
amod
=
DEBUG_CurrProcess
->
modules
;
DBG_MODULE
*
res
=
NULL
;
for
(
wmod
=
DEBUG_CurrProcess
->
modules
;
wmod
;
wmod
=
wmod
->
next
)
{
if
((
type
==
DM_TYPE_UNKNOWN
||
type
==
wmod
->
type
)
&&
(
u_long
)
addr
>=
(
u_long
)
wmod
->
load_addr
&&
(
!
res
||
res
->
load_addr
<
wmod
->
load_addr
))
res
=
wmod
;
}
for
(
i
=
0
;
i
<
DEBUG_CurrProcess
->
num_modules
;
i
++
)
{
if
((
type
==
DMT_UNKNOWN
||
type
==
amod
[
i
]
->
type
)
&&
(
u_long
)
addr
>=
(
u_long
)
amod
[
i
]
->
load_addr
&&
(
!
res
||
res
->
load_addr
<
amod
[
i
]
->
load_addr
))
res
=
amod
[
i
]
;
}
return
res
;
}
/***********************************************************************
* DEBUG_FindModuleByHandle
*/
DBG_MODULE
*
DEBUG_FindModuleByHandle
(
HANDLE
handle
,
int
type
)
DBG_MODULE
*
DEBUG_FindModuleByHandle
(
HANDLE
handle
,
enum
DbgModuleType
type
)
{
DBG_MODULE
*
wmod
;
for
(
wmod
=
DEBUG_CurrProcess
->
modules
;
wmod
;
wmod
=
wmod
->
next
)
{
if
((
type
==
DM_TYPE_UNKNOWN
||
type
==
wmod
->
type
)
&&
handle
==
wmod
->
handle
)
break
;
}
return
wmod
;
int
i
;
DBG_MODULE
**
amod
=
DEBUG_CurrProcess
->
modules
;
for
(
i
=
0
;
i
<
DEBUG_CurrProcess
->
num_modules
;
i
++
)
{
if
((
type
==
DMT_UNKNOWN
||
type
==
amod
[
i
]
->
type
)
&&
handle
==
amod
[
i
]
->
handle
)
return
amod
[
i
];
}
return
NULL
;
}
/***********************************************************************
...
...
@@ -95,14 +103,12 @@ DBG_MODULE* DEBUG_FindModuleByHandle(HANDLE handle, int type)
*/
DBG_MODULE
*
DEBUG_GetProcessMainModule
(
DBG_PROCESS
*
process
)
{
DBG_MODULE
*
wmod
;
if
(
!
process
)
return
NULL
;
/* main module is the first to be loaded on a given process, so it's the last on
* the list */
for
(
wmod
=
process
->
modules
;
wmod
&&
wmod
->
next
;
wmod
=
wmod
->
next
);
return
wmod
;
if
(
!
process
||
!
process
->
num_modules
)
return
NULL
;
/* main module is the first to be loaded on a given process, so it's the first
* in the array */
assert
(
process
->
modules
[
0
]
->
main
);
return
process
->
modules
[
0
];
}
/***********************************************************************
...
...
@@ -111,13 +117,12 @@ DBG_MODULE* DEBUG_GetProcessMainModule(DBG_PROCESS* process)
* ELF modules are also entered into the list - this is so that we
* can make 'info shared' types of displays possible.
*/
DBG_MODULE
*
DEBUG_RegisterELFModule
(
u_long
load_addr
,
const
char
*
name
)
DBG_MODULE
*
DEBUG_RegisterELFModule
(
u_long
load_addr
,
u_long
size
,
const
char
*
name
)
{
DBG_MODULE
*
wmod
=
DEBUG_AddModule
(
name
,
DM
_TYPE_ELF
,
(
void
*
)
load_addr
,
0
);
DBG_MODULE
*
wmod
=
DEBUG_AddModule
(
name
,
DM
T_ELF
,
(
void
*
)
load_addr
,
size
,
0
);
if
(
!
wmod
)
return
NULL
;
wmod
->
status
=
DM_STATUS_LOADED
;
DEBUG_CurrProcess
->
next_index
++
;
return
wmod
;
...
...
@@ -127,9 +132,9 @@ DBG_MODULE* DEBUG_RegisterELFModule(u_long load_addr, const char* name)
* DEBUG_RegisterPEModule
*
*/
DBG_MODULE
*
DEBUG_RegisterPEModule
(
HMODULE
hModule
,
u_long
load_addr
,
const
char
*
module_name
)
DBG_MODULE
*
DEBUG_RegisterPEModule
(
HMODULE
hModule
,
u_long
load_addr
,
u_long
size
,
const
char
*
module_name
)
{
DBG_MODULE
*
wmod
=
DEBUG_AddModule
(
module_name
,
DM
_TYPE_PE
,
(
void
*
)
load_addr
,
hModule
);
DBG_MODULE
*
wmod
=
DEBUG_AddModule
(
module_name
,
DM
T_PE
,
(
void
*
)
load_addr
,
size
,
hModule
);
if
(
!
wmod
)
return
NULL
;
...
...
@@ -142,13 +147,12 @@ DBG_MODULE* DEBUG_RegisterPEModule(HMODULE hModule, u_long load_addr, const char
* DEBUG_RegisterNEModule
*
*/
DBG_MODULE
*
DEBUG_RegisterNEModule
(
HMODULE
hModule
,
void
*
load_addr
,
const
char
*
module_name
)
DBG_MODULE
*
DEBUG_RegisterNEModule
(
HMODULE
hModule
,
void
*
load_addr
,
u_long
size
,
const
char
*
module_name
)
{
DBG_MODULE
*
wmod
=
DEBUG_AddModule
(
module_name
,
DM
_TYPE_NE
,
load_addr
,
hModule
);
DBG_MODULE
*
wmod
=
DEBUG_AddModule
(
module_name
,
DM
T_NE
,
load_addr
,
size
,
hModule
);
if
(
!
wmod
)
return
NULL
;
wmod
->
status
=
DM_STATUS_LOADED
;
DEBUG_CurrProcess
->
next_index
++
;
return
wmod
;
}
...
...
@@ -252,58 +256,85 @@ static void DEBUG_LoadModule16(HMODULE hModule, NE_MODULE* module, char* moduleA
*/
void
DEBUG_LoadModule32
(
const
char
*
name
,
HANDLE
hFile
,
DWORD
base
)
{
IMAGE_NT_HEADERS
pe_header
;
DWORD
nth_ofs
;
DBG_MODULE
*
wmod
=
NULL
;
int
i
;
IMAGE_SECTION_HEADER
pe_seg
;
DWORD
pe_seg_ofs
;
DWORD
size
=
0
;
enum
DbgInfoLoad
dil
=
DIL_ERROR
;
/* grab PE Header */
if
(
!
DEBUG_READ_MEM_VERBOSE
((
void
*
)(
base
+
OFFSET_OF
(
IMAGE_DOS_HEADER
,
e_lfanew
)),
&
nth_ofs
,
sizeof
(
nth_ofs
))
||
!
DEBUG_READ_MEM_VERBOSE
((
void
*
)(
base
+
nth_ofs
),
&
pe_header
,
sizeof
(
pe_header
)))
return
;
pe_seg_ofs
=
nth_ofs
+
OFFSET_OF
(
IMAGE_NT_HEADERS
,
OptionalHeader
)
+
pe_header
.
FileHeader
.
SizeOfOptionalHeader
;
for
(
i
=
0
;
i
<
pe_header
.
FileHeader
.
NumberOfSections
;
i
++
,
pe_seg_ofs
+=
sizeof
(
pe_seg
))
{
if
(
!
DEBUG_READ_MEM_VERBOSE
((
void
*
)(
base
+
pe_seg_ofs
),
&
pe_seg
,
sizeof
(
pe_seg
)))
continue
;
if
(
size
<
pe_seg
.
VirtualAddress
+
pe_seg
.
SizeOfRawData
)
size
=
pe_seg
.
VirtualAddress
+
pe_seg
.
SizeOfRawData
;
}
/* FIXME: we make the assumption that hModule == base */
wmod
=
DEBUG_RegisterPEModule
((
HMODULE
)
base
,
base
,
size
,
name
);
if
(
wmod
)
{
dil
=
DEBUG_RegisterStabsDebugInfo
(
wmod
,
hFile
,
&
pe_header
,
nth_ofs
);
if
(
dil
!=
DIL_LOADED
)
dil
=
DEBUG_RegisterMSCDebugInfo
(
wmod
,
hFile
,
&
pe_header
,
nth_ofs
);
if
(
dil
!=
DIL_LOADED
)
dil
=
DEBUG_RegisterPEDebugInfo
(
wmod
,
hFile
,
&
pe_header
,
nth_ofs
);
}
if
(
wmod
)
wmod
->
dil
=
dil
;
DEBUG_ReportDIL
(
dil
,
"32bit DLL"
,
name
,
base
);
}
/***********************************************************************
* DEBUG_RegisterPEDebugInfo
*/
enum
DbgInfoLoad
DEBUG_RegisterPEDebugInfo
(
DBG_MODULE
*
wmod
,
HANDLE
hFile
,
void
*
_nth
,
unsigned
long
nth_ofs
)
{
DBG_VALUE
value
;
char
buffer
[
512
];
char
bufstr
[
256
];
int
i
;
IMAGE_NT_HEADERS
pe_header
;
DWORD
pe_header_ofs
;
IMAGE_SECTION_HEADER
pe_seg
;
DWORD
pe_seg_ofs
;
IMAGE_DATA_DIRECTORY
dir
;
DWORD
dir_ofs
;
DBG_MODULE
*
wmod
;
const
char
*
prefix
;
/* FIXME: we make the assumption that hModule == base */
wmod
=
DEBUG_RegisterPEModule
((
HMODULE
)
base
,
base
,
name
);
const
char
*
prefix
;
IMAGE_NT_HEADERS
*
nth
=
(
PIMAGE_NT_HEADERS
)
_nth
;
DWORD
base
=
(
u_long
)
wmod
->
load_addr
;
DEBUG_Printf
(
DBG_CHN_TRACE
,
"Registring 32bit DLL '%s' at %08lx
\n
"
,
name
,
base
);
value
.
type
=
NULL
;
value
.
cookie
=
DV_TARGET
;
value
.
addr
.
seg
=
0
;
value
.
addr
.
off
=
0
;
/* grab PE Header */
if
(
!
DEBUG_READ_MEM_VERBOSE
((
void
*
)(
base
+
OFFSET_OF
(
IMAGE_DOS_HEADER
,
e_lfanew
)),
&
pe_header_ofs
,
sizeof
(
pe_header_ofs
))
||
!
DEBUG_READ_MEM_VERBOSE
((
void
*
)(
base
+
pe_header_ofs
),
&
pe_header
,
sizeof
(
pe_header
)))
return
;
if
(
wmod
)
{
DEBUG_RegisterStabsDebugInfo
(
wmod
,
hFile
,
&
pe_header
,
pe_header_ofs
);
DEBUG_RegisterMSCDebugInfo
(
wmod
,
hFile
,
&
pe_header
,
pe_header_ofs
);
}
/* Add start of DLL */
value
.
addr
.
off
=
base
;
if
((
prefix
=
strrchr
(
name
,
'\\'
)))
prefix
++
;
else
prefix
=
name
;
if
((
prefix
=
strrchr
(
wmod
->
module_
name
,
'\\'
)))
prefix
++
;
else
prefix
=
wmod
->
module_
name
;
DEBUG_AddSymbol
(
prefix
,
&
value
,
NULL
,
SYM_WIN32
|
SYM_FUNC
);
/* Add entry point */
wsnprintf
(
buffer
,
sizeof
(
buffer
),
"%s.EntryPoint"
,
prefix
);
value
.
addr
.
off
=
base
+
pe_header
.
OptionalHeader
.
AddressOfEntryPoint
;
value
.
addr
.
off
=
base
+
nth
->
OptionalHeader
.
AddressOfEntryPoint
;
DEBUG_AddSymbol
(
buffer
,
&
value
,
NULL
,
SYM_WIN32
|
SYM_FUNC
);
/* Add start of sections */
pe_seg_ofs
=
pe_header
_ofs
+
OFFSET_OF
(
IMAGE_NT_HEADERS
,
OptionalHeader
)
+
pe_header
.
FileHeader
.
SizeOfOptionalHeader
;
pe_seg_ofs
=
nth
_ofs
+
OFFSET_OF
(
IMAGE_NT_HEADERS
,
OptionalHeader
)
+
nth
->
FileHeader
.
SizeOfOptionalHeader
;
for
(
i
=
0
;
i
<
pe_header
.
FileHeader
.
NumberOfSections
;
i
++
,
pe_seg_ofs
+=
sizeof
(
pe_seg
))
{
for
(
i
=
0
;
i
<
nth
->
FileHeader
.
NumberOfSections
;
i
++
,
pe_seg_ofs
+=
sizeof
(
pe_seg
))
{
if
(
!
DEBUG_READ_MEM_VERBOSE
((
void
*
)(
base
+
pe_seg_ofs
),
&
pe_seg
,
sizeof
(
pe_seg
)))
continue
;
wsnprintf
(
buffer
,
sizeof
(
buffer
),
"%s.%s"
,
prefix
,
pe_seg
.
Name
);
...
...
@@ -312,7 +343,7 @@ void DEBUG_LoadModule32(const char* name, HANDLE hFile, DWORD base)
}
/* Add exported functions */
dir_ofs
=
pe_header
_ofs
+
dir_ofs
=
nth
_ofs
+
OFFSET_OF
(
IMAGE_NT_HEADERS
,
OptionalHeader
.
DataDirectory
[
IMAGE_DIRECTORY_ENTRY_EXPORT
]);
if
(
DEBUG_READ_MEM_VERBOSE
((
void
*
)(
base
+
dir_ofs
),
&
dir
,
sizeof
(
dir
))
&&
dir
.
Size
)
{
...
...
@@ -362,6 +393,8 @@ void DEBUG_LoadModule32(const char* name, HANDLE hFile, DWORD base)
DBG_free
(
ordinals
);
DBG_free
(
names
);
}
/* no real debug info, only entry points */
return
DIL_NOINFO
;
}
/***********************************************************************
...
...
@@ -416,67 +449,151 @@ int DEBUG_LoadEntryPoints(const char* pfx)
return
first
;
}
/***********************************************************************
* DEBUG_InfoShare
*
* Display shared libarary information.
*/
void
DEBUG_InfoShare
(
void
)
void
DEBUG_ReportDIL
(
enum
DbgInfoLoad
dil
,
const
char
*
pfx
,
const
char
*
filename
,
DWORD
load_addr
)
{
DBG_MODULE
*
wmod
;
const
char
*
xtype
;
DEBUG_Printf
(
DBG_CHN_MESG
,
"Address
\t\t
Module
\t
Name
\n
"
);
for
(
wmod
=
DEBUG_CurrProcess
->
modules
;
wmod
;
wmod
=
wmod
->
next
)
{
switch
(
wmod
->
type
)
{
case
DM_TYPE_NE
:
xtype
=
"NE"
;
break
;
case
DM_TYPE_PE
:
xtype
=
"PE"
;
break
;
case
DM_TYPE_ELF
:
xtype
=
"ELF"
;
break
;
default:
xtype
=
"???"
;
break
;
}
DEBUG_Printf
(
DBG_CHN_MESG
,
"0x%8.8x
\t
(%s)
\t
%s
\n
"
,
(
unsigned
int
)
wmod
->
load_addr
,
xtype
,
wmod
->
module_name
);
const
char
*
fmt
;
switch
(
dil
)
{
case
DIL_DEFERRED
:
fmt
=
"Deferring debug information loading for %s '%s' (0x%08x)
\n
"
;
break
;
case
DIL_LOADED
:
fmt
=
"Loaded debug information from %s '%s' (0x%08x)
\n
"
;
break
;
case
DIL_NOINFO
:
fmt
=
"No debug information in %s '%s' (0x%08x)
\n
"
;
break
;
case
DIL_ERROR
:
fmt
=
"Can't find file for %s '%s' (0x%08x)
\n
"
;
break
;
default:
DEBUG_Printf
(
DBG_CHN_ERR
,
"Oooocch (%d)
\n
"
,
dil
);
return
;
}
DEBUG_Printf
(
DBG_CHN_MESG
,
fmt
,
pfx
,
filename
,
load_addr
);
}
static
const
char
*
DEBUG_GetModuleType
(
int
type
)
static
const
char
*
DEBUG_GetModuleType
(
enum
DbgModuleType
type
)
{
switch
(
type
)
{
case
DM
_TYPE_NE
:
return
"NE"
;
case
DM
_TYPE_PE
:
return
"PE"
;
case
DM
_TYPE_ELF
:
return
"ELF"
;
default:
return
"???"
;;
case
DM
T_NE
:
return
"NE"
;
case
DM
T_PE
:
return
"PE"
;
case
DM
T_ELF
:
return
"ELF"
;
default:
return
"???"
;;
}
}
static
const
char
*
DEBUG_GetModuleStatus
(
int
status
)
static
const
char
*
DEBUG_GetDbgInfo
(
enum
DbgInfoLoad
dil
)
{
switch
(
status
)
{
case
DM_STATUS_NEW
:
return
"deferred"
;
case
DM_STATUS_LOADED
:
return
"ok"
;
case
DM_STATUS_ERROR
:
return
"error"
;
default:
return
"???"
;
switch
(
dil
)
{
case
DIL_LOADED
:
return
"loaded"
;
case
DIL_DEFERRED
:
return
"deferred"
;
case
DIL_NOINFO
:
return
"none"
;
case
DIL_ERROR
:
return
"error"
;
default:
return
"?"
;
}
}
/***********************************************************************
* DEBUG_
* DEBUG_ModuleCompare
*
* returns -1 is p1 < p2, 0 is p1 == p2, +1 if p1 > p2
* order used is order on load_addr of a module
*/
static
int
DEBUG_ModuleCompare
(
const
void
*
p1
,
const
void
*
p2
)
{
return
(
*
((
const
DBG_MODULE
**
)
p1
))
->
load_addr
-
(
*
((
const
DBG_MODULE
**
)
p2
))
->
load_addr
;
}
/***********************************************************************
* DEBUG_IsContainer
*
* returns TRUE is wmod_child is contained (inside bounds) of wmod_cntnr
*/
static
BOOL
inline
DEBUG_IsContainer
(
const
DBG_MODULE
*
wmod_cntnr
,
const
DBG_MODULE
*
wmod_child
)
{
return
wmod_cntnr
->
load_addr
<
wmod_child
->
load_addr
&&
(
DWORD
)
wmod_cntnr
->
load_addr
+
wmod_cntnr
->
size
>
(
DWORD
)
wmod_child
->
load_addr
+
wmod_child
->
size
;
}
static
void
DEBUG_InfoShareModule
(
const
DBG_MODULE
*
module
,
int
ident
)
{
if
(
ident
)
DEBUG_Printf
(
DBG_CHN_MESG
,
"
\\
-"
);
DEBUG_Printf
(
DBG_CHN_MESG
,
"%s
\t
0x%08lx-%08lx
\t
%s
\n
"
,
DEBUG_GetModuleType
(
module
->
type
),
(
DWORD
)
module
->
load_addr
,
(
DWORD
)
module
->
load_addr
+
module
->
size
,
module
->
module_name
);
}
/***********************************************************************
* DEBUG_InfoShare
*
* Display shared libarary information.
*/
void
DEBUG_InfoShare
(
void
)
{
DBG_MODULE
**
ref
;
int
i
,
j
;
ref
=
DBG_alloc
(
sizeof
(
DBG_MODULE
*
)
*
DEBUG_CurrProcess
->
num_modules
);
if
(
!
ref
)
return
;
DEBUG_Printf
(
DBG_CHN_MESG
,
"Module
\t
Address
\t\t\t
Name
\t
%d modules
\n
"
,
DEBUG_CurrProcess
->
num_modules
);
memcpy
(
ref
,
DEBUG_CurrProcess
->
modules
,
sizeof
(
DBG_MODULE
*
)
*
DEBUG_CurrProcess
->
num_modules
);
qsort
(
ref
,
DEBUG_CurrProcess
->
num_modules
,
sizeof
(
DBG_MODULE
*
),
DEBUG_ModuleCompare
);
for
(
i
=
0
;
i
<
DEBUG_CurrProcess
->
num_modules
;
i
++
)
{
switch
(
ref
[
i
]
->
type
)
{
case
DMT_ELF
:
DEBUG_InfoShareModule
(
ref
[
i
],
0
);
for
(
j
=
0
;
j
<
DEBUG_CurrProcess
->
num_modules
;
j
++
)
{
if
(
ref
[
j
]
->
type
!=
DMT_ELF
&&
DEBUG_IsContainer
(
ref
[
i
],
ref
[
j
]))
DEBUG_InfoShareModule
(
ref
[
j
],
1
);
}
break
;
case
DMT_NE
:
case
DMT_PE
:
/* check module is not in ELF */
for
(
j
=
0
;
j
<
DEBUG_CurrProcess
->
num_modules
;
j
++
)
{
if
(
ref
[
j
]
->
type
==
DMT_ELF
&&
DEBUG_IsContainer
(
ref
[
j
],
ref
[
i
]))
break
;
}
if
(
j
>=
DEBUG_CurrProcess
->
num_modules
)
DEBUG_InfoShareModule
(
ref
[
i
],
0
);
break
;
default:
DEBUG_Printf
(
DBG_CHN_ERR
,
"Unknown type (%d)
\n
"
,
ref
[
i
]
->
type
);
}
}
DBG_free
(
ref
);
}
/***********************************************************************
* DEBUG_DumpModule
* Display information about a given module (DLL or EXE)
*/
void
DEBUG_DumpModule
(
DWORD
mod
)
{
DBG_MODULE
*
wmod
;
if
(
!
(
wmod
=
DEBUG_FindModuleByHandle
(
mod
,
DM
_TYPE
_UNKNOWN
))
&&
!
(
wmod
=
DEBUG_FindModuleByAddr
((
void
*
)
mod
,
DM
_TYPE
_UNKNOWN
)))
{
if
(
!
(
wmod
=
DEBUG_FindModuleByHandle
(
mod
,
DM
T
_UNKNOWN
))
&&
!
(
wmod
=
DEBUG_FindModuleByAddr
((
void
*
)
mod
,
DM
T
_UNKNOWN
)))
{
DEBUG_Printf
(
DBG_CHN_MESG
,
"'0x%08lx' is not a valid module handle or address
\n
"
,
mod
);
return
;
}
DEBUG_Printf
(
DBG_CHN_MESG
,
"Module '%s' (handle=0x%08x) at 0x%8.8x (%s/%s)
\n
"
,
wmod
->
module_name
,
wmod
->
handle
,
(
unsigned
int
)
wmod
->
load_addr
,
DEBUG_GetModuleType
(
wmod
->
type
),
DEBUG_GetModuleStatus
(
wmod
->
status
));
DEBUG_Printf
(
DBG_CHN_MESG
,
"Module '%s' (handle=0x%08x) 0x%08lx-0x%08lx (%s, debug info %s)
\n
"
,
wmod
->
module_name
,
wmod
->
handle
,
(
DWORD
)
wmod
->
load_addr
,
(
DWORD
)
wmod
->
load_addr
+
wmod
->
size
,
DEBUG_GetModuleType
(
wmod
->
type
),
DEBUG_GetDbgInfo
(
wmod
->
dil
));
}
/***********************************************************************
...
...
@@ -486,22 +603,26 @@ void DEBUG_DumpModule(DWORD mod)
*/
void
DEBUG_WalkModules
(
void
)
{
DBG_MODULE
*
wmod
;
const
char
*
xtype
;
DEBUG_Printf
(
DBG_CHN_MESG
,
"Address
\t\t
Module
\t
Name
\n
"
);
for
(
wmod
=
DEBUG_CurrProcess
->
modules
;
wmod
;
wmod
=
wmod
->
next
)
{
switch
(
wmod
->
type
)
{
case
DM_TYPE_NE
:
xtype
=
"NE"
;
break
;
case
DM_TYPE_PE
:
xtype
=
"PE"
;
break
;
case
DM_TYPE_ELF
:
continue
;
default:
xtype
=
"???"
;
break
;
}
DEBUG_Printf
(
DBG_CHN_MESG
,
"0x%8.8x
\t
(%s)
\t
%s
\n
"
,
(
unsigned
int
)
wmod
->
load_addr
,
DEBUG_GetModuleType
(
wmod
->
type
),
wmod
->
module_name
);
DBG_MODULE
**
amod
;
int
i
;
DEBUG_Printf
(
DBG_CHN_MESG
,
"Address
\t\t\t
Module
\t
Name
\n
"
);
amod
=
DBG_alloc
(
sizeof
(
DBG_MODULE
*
)
*
DEBUG_CurrProcess
->
num_modules
);
if
(
!
amod
)
return
;
memcpy
(
amod
,
DEBUG_CurrProcess
->
modules
,
sizeof
(
DBG_MODULE
*
)
*
DEBUG_CurrProcess
->
num_modules
);
qsort
(
amod
,
DEBUG_CurrProcess
->
num_modules
,
sizeof
(
DBG_MODULE
*
),
DEBUG_ModuleCompare
);
for
(
i
=
0
;
i
<
DEBUG_CurrProcess
->
num_modules
;
i
++
)
{
if
(
amod
[
i
]
->
type
==
DMT_ELF
)
continue
;
DEBUG_Printf
(
DBG_CHN_MESG
,
"0x%08lx-%08lx
\t
(%s)
\t
%s
\n
"
,
(
DWORD
)
amod
[
i
]
->
load_addr
,
(
DWORD
)
amod
[
i
]
->
load_addr
+
amod
[
i
]
->
size
,
DEBUG_GetModuleType
(
amod
[
i
]
->
type
),
amod
[
i
]
->
module_name
);
}
DBG_free
(
amod
);
}
debugger/msc.c
View file @
e939206f
...
...
@@ -27,7 +27,6 @@
#include "neexe.h"
#include "file.h"
typedef
struct
{
DWORD
from
;
...
...
@@ -35,7 +34,7 @@ typedef struct
}
OMAP_DATA
;
typedef
struct
typedef
struct
tagMSC_DBG_INFO
{
int
nsect
;
PIMAGE_SECTION_HEADER
sectp
;
...
...
@@ -45,10 +44,6 @@ typedef struct
}
MSC_DBG_INFO
;
#define MSC_INFO(module) ((MSC_DBG_INFO*)((module)->extra_info))
/*========================================================================
* Debug file access helper routines
*/
...
...
@@ -209,7 +204,7 @@ static void DEBUG_AddCoffSymbol( struct CoffFile* coff_file, struct name_hash* s
coff_file
->
entries
[
coff_file
->
neps
++
]
=
sym
;
}
static
BOOL
DEBUG_ProcessCoff
(
DBG_MODULE
*
module
,
LPBYTE
root
)
static
enum
DbgInfoLoad
DEBUG_ProcessCoff
(
DBG_MODULE
*
module
,
LPBYTE
root
)
{
PIMAGE_AUX_SYMBOL
aux
;
PIMAGE_COFF_SYMBOLS_HEADER
coff
;
...
...
@@ -227,7 +222,7 @@ static BOOL DEBUG_ProcessCoff( DBG_MODULE *module, LPBYTE root )
const
char
*
nampnt
;
int
naux
;
DBG_VALUE
new_value
;
int
rtn
=
FALSE
;
enum
DbgInfoLoad
dil
=
DIL_ERROR
;
DEBUG_Printf
(
DBG_CHN_TRACE
,
"Processing COFF symbols...
\n
"
);
...
...
@@ -344,7 +339,7 @@ static BOOL DEBUG_ProcessCoff( DBG_MODULE *module, LPBYTE root )
&&
(
naux
==
0
)
&&
(
coff_sym
->
SectionNumber
==
1
)
)
{
DWORD
base
=
MSC_INFO
(
module
)
->
sectp
[
coff_sym
->
SectionNumber
-
1
].
VirtualAddress
;
DWORD
base
=
module
->
msc_info
->
sectp
[
coff_sym
->
SectionNumber
-
1
].
VirtualAddress
;
/*
* This is a normal static function when naux == 0.
* Just register it. The current file is the correct
...
...
@@ -373,7 +368,7 @@ static BOOL DEBUG_ProcessCoff( DBG_MODULE *module, LPBYTE root )
&&
(
coff_sym
->
SectionNumber
>
0
)
)
{
const
char
*
this_file
=
NULL
;
DWORD
base
=
MSC_INFO
(
module
)
->
sectp
[
coff_sym
->
SectionNumber
-
1
].
VirtualAddress
;
DWORD
base
=
module
->
msc_info
->
sectp
[
coff_sym
->
SectionNumber
-
1
].
VirtualAddress
;
nampnt
=
DEBUG_GetCoffName
(
coff_sym
,
coff_strtab
);
new_value
.
addr
.
seg
=
0
;
...
...
@@ -411,7 +406,7 @@ static BOOL DEBUG_ProcessCoff( DBG_MODULE *module, LPBYTE root )
if
(
(
coff_sym
->
StorageClass
==
IMAGE_SYM_CLASS_EXTERNAL
)
&&
(
coff_sym
->
SectionNumber
>
0
)
)
{
DWORD
base
=
MSC_INFO
(
module
)
->
sectp
[
coff_sym
->
SectionNumber
-
1
].
VirtualAddress
;
DWORD
base
=
module
->
msc_info
->
sectp
[
coff_sym
->
SectionNumber
-
1
].
VirtualAddress
;
/*
* Similar to above, but for the case of data symbols.
* These aren't treated as entrypoints.
...
...
@@ -517,7 +512,7 @@ static BOOL DEBUG_ProcessCoff( DBG_MODULE *module, LPBYTE root )
}
}
rtn
=
TRUE
;
dil
=
DIL_LOADED
;
if
(
coff_files
.
files
!=
NULL
)
{
...
...
@@ -531,7 +526,7 @@ static BOOL DEBUG_ProcessCoff( DBG_MODULE *module, LPBYTE root )
DBG_free
(
coff_files
.
files
);
}
return
(
rtn
)
;
return
dil
;
}
...
...
@@ -2030,8 +2025,8 @@ union codeview_symbol
static
unsigned
int
DEBUG_MapCVOffset
(
DBG_MODULE
*
module
,
unsigned
int
offset
)
{
int
nomap
=
MSC_INFO
(
module
)
->
nomap
;
OMAP_DATA
*
omapp
=
MSC_INFO
(
module
)
->
omapp
;
int
nomap
=
module
->
msc_info
->
nomap
;
OMAP_DATA
*
omapp
=
module
->
msc_info
->
omapp
;
int
i
;
if
(
!
nomap
||
!
omapp
)
...
...
@@ -2050,8 +2045,8 @@ DEBUG_AddCVSymbol( DBG_MODULE *module, char *name, int namelen,
int
type
,
int
seg
,
int
offset
,
int
size
,
int
cookie
,
int
flags
,
struct
codeview_linetab_hdr
*
linetab
)
{
int
nsect
=
MSC_INFO
(
module
)
->
nsect
;
PIMAGE_SECTION_HEADER
sectp
=
MSC_INFO
(
module
)
->
sectp
;
int
nsect
=
module
->
msc_info
->
nsect
;
PIMAGE_SECTION_HEADER
sectp
=
module
->
msc_info
->
sectp
;
struct
name_hash
*
symbol
;
char
symname
[
PATH_MAX
];
...
...
@@ -2529,8 +2524,10 @@ static void pdb_convert_symbols_header( PDB_SYMBOLS *symbols,
}
}
static
int
DEBUG_ProcessPDBFile
(
DBG_MODULE
*
module
,
const
char
*
filename
,
DWORD
timestamp
)
static
enum
DbgInfoLoad
DEBUG_ProcessPDBFile
(
DBG_MODULE
*
module
,
const
char
*
filename
,
DWORD
timestamp
)
{
enum
DbgInfoLoad
dil
=
DIL_ERROR
;
HANDLE
hFile
,
hMap
;
char
*
image
=
NULL
;
PDB_HEADER
*
pdb
=
NULL
;
...
...
@@ -2690,6 +2687,7 @@ static int DEBUG_ProcessPDBFile( DBG_MODULE *module, const char *filename, DWORD
file
=
(
char
*
)(
(
DWORD
)(
file_name
+
strlen
(
file_name
)
+
1
+
3
)
&
~
3
);
}
dil
=
DIL_LOADED
;
leave:
...
...
@@ -2706,7 +2704,7 @@ static int DEBUG_ProcessPDBFile( DBG_MODULE *module, const char *filename, DWORD
DEBUG_UnmapDebugInfoFile
(
hFile
,
hMap
,
image
);
return
TRUE
;
return
dil
;
}
...
...
@@ -2759,10 +2757,10 @@ typedef struct _CV_DIRECTORY_ENTRY
#define sstSrcModule 0x127
static
BOOL
DEBUG_ProcessCodeView
(
DBG_MODULE
*
module
,
LPBYTE
root
)
static
enum
DbgInfoLoad
DEBUG_ProcessCodeView
(
DBG_MODULE
*
module
,
LPBYTE
root
)
{
PCODEVIEW_HEADER
cv
=
(
PCODEVIEW_HEADER
)
root
;
BOOL
retv
=
FALSE
;
enum
DbgInfoLoad
dil
=
DIL_ERROR
;
switch
(
cv
->
dwSignature
)
{
...
...
@@ -2806,7 +2804,7 @@ static BOOL DEBUG_ProcessCodeView( DBG_MODULE *module, LPBYTE root )
}
}
retv
=
TRUE
;
dil
=
DIL_LOADED
;
break
;
}
...
...
@@ -2814,7 +2812,7 @@ static BOOL DEBUG_ProcessCodeView( DBG_MODULE *module, LPBYTE root )
{
PCODEVIEW_PDB_DATA
pdb
=
(
PCODEVIEW_PDB_DATA
)(
cv
+
1
);
retv
=
DEBUG_ProcessPDBFile
(
module
,
pdb
->
name
,
pdb
->
timestamp
);
dil
=
DEBUG_ProcessPDBFile
(
module
,
pdb
->
name
,
pdb
->
timestamp
);
break
;
}
...
...
@@ -2824,51 +2822,81 @@ static BOOL DEBUG_ProcessCodeView( DBG_MODULE *module, LPBYTE root )
break
;
}
return
retv
;
return
dil
;
}
/*========================================================================
* Process debug directory.
*/
static
BOOL
DEBUG_ProcessDebugDirectory
(
DBG_MODULE
*
module
,
LPBYTE
file_map
,
PIMAGE_DEBUG_DIRECTORY
dbg
,
int
nDbg
)
static
enum
DbgInfoLoad
DEBUG_ProcessDebugDirectory
(
DBG_MODULE
*
module
,
LPBYTE
file_map
,
PIMAGE_DEBUG_DIRECTORY
dbg
,
int
nDbg
)
{
BOOL
retv
=
FALSE
;
enum
DbgInfoLoad
dil
=
DIL_ERROR
;
int
i
;
/* First, watch out for OMAP data */
for
(
i
=
0
;
i
<
nDbg
;
i
++
)
if
(
dbg
[
i
].
Type
==
IMAGE_DEBUG_TYPE_OMAP_FROM_SRC
)
{
MSC_INFO
(
module
)
->
nomap
=
dbg
[
i
].
SizeOfData
/
sizeof
(
OMAP_DATA
);
MSC_INFO
(
module
)
->
omapp
=
(
OMAP_DATA
*
)(
file_map
+
dbg
[
i
].
PointerToRawData
);
module
->
msc_info
->
nomap
=
dbg
[
i
].
SizeOfData
/
sizeof
(
OMAP_DATA
);
module
->
msc_info
->
omapp
=
(
OMAP_DATA
*
)(
file_map
+
dbg
[
i
].
PointerToRawData
);
break
;
}
/* Now, try to parse CodeView debug info */
for
(
i
=
0
;
!
retv
&&
i
<
nDbg
;
i
++
)
for
(
i
=
0
;
dil
!=
DIL_LOADED
&&
i
<
nDbg
;
i
++
)
if
(
dbg
[
i
].
Type
==
IMAGE_DEBUG_TYPE_CODEVIEW
)
retv
=
DEBUG_ProcessCodeView
(
module
,
file_map
+
dbg
[
i
].
PointerToRawData
);
dil
=
DEBUG_ProcessCodeView
(
module
,
file_map
+
dbg
[
i
].
PointerToRawData
);
/* If not found, try to parse COFF debug info */
for
(
i
=
0
;
!
retv
&&
i
<
nDbg
;
i
++
)
for
(
i
=
0
;
dil
!=
DIL_LOADED
&&
i
<
nDbg
;
i
++
)
if
(
dbg
[
i
].
Type
==
IMAGE_DEBUG_TYPE_COFF
)
retv
=
DEBUG_ProcessCoff
(
module
,
file_map
+
dbg
[
i
].
PointerToRawData
);
dil
=
DEBUG_ProcessCoff
(
module
,
file_map
+
dbg
[
i
].
PointerToRawData
);
#if 0
/* FIXME: this should be supported... this is the debug information for
* functions compiled without a frame pointer (FPO = frame pointer omission)
* the associated data helps finding out the relevant information
*/
for ( i = 0; i < nDbg; i++ )
if ( dbg[i].Type == IMAGE_DEBUG_TYPE_FPO )
DEBUG_Printf(DBG_CHN_MESG, "This guy has FPO information\n");
#define FRAME_FPO 0
#define FRAME_TRAP 1
#define FRAME_TSS 2
typedef struct _FPO_DATA {
DWORD ulOffStart; /* offset 1st byte of function code */
DWORD cbProcSize; /* # bytes in function */
DWORD cdwLocals; /* # bytes in locals/4 */
WORD cdwParams; /* # bytes in params/4 */
WORD cbProlog : 8; /* # bytes in prolog */
WORD cbRegs : 3; /* # regs saved */
WORD fHasSEH : 1; /* TRUE if SEH in func */
WORD fUseBP : 1; /* TRUE if EBP has been allocated */
WORD reserved : 1; /* reserved for future use */
WORD cbFrame : 2; /* frame type */
} FPO_DATA;
#endif
return
retv
;
return
dil
;
}
/*========================================================================
* Process DBG file.
*/
static
BOOL
DEBUG_ProcessDBGFile
(
DBG_MODULE
*
module
,
const
char
*
filename
,
DWORD
timestamp
)
static
enum
DbgInfoLoad
DEBUG_ProcessDBGFile
(
DBG_MODULE
*
module
,
const
char
*
filename
,
DWORD
timestamp
)
{
BOOL
retv
=
FALSE
;
enum
DbgInfoLoad
dil
=
DIL_ERROR
;
HANDLE
hFile
=
0
,
hMap
=
0
;
LPBYTE
file_map
=
NULL
;
PIMAGE_SEPARATE_DEBUG_HEADER
hdr
;
...
...
@@ -2905,22 +2933,22 @@ static BOOL DEBUG_ProcessDBGFile( DBG_MODULE *module, const char *filename, DWOR
nDbg
=
hdr
->
DebugDirectorySize
/
sizeof
(
*
dbg
);
retv
=
DEBUG_ProcessDebugDirectory
(
module
,
file_map
,
dbg
,
nDbg
);
dil
=
DEBUG_ProcessDebugDirectory
(
module
,
file_map
,
dbg
,
nDbg
);
leave:
DEBUG_UnmapDebugInfoFile
(
hFile
,
hMap
,
file_map
);
return
retv
;
return
dil
;
}
/*========================================================================
* Process MSC debug information in PE file.
*/
int
DEBUG_RegisterMSCDebugInfo
(
DBG_MODULE
*
module
,
HANDLE
hFile
,
void
*
_nth
,
unsigned
long
nth_ofs
)
enum
DbgInfoLoad
DEBUG_RegisterMSCDebugInfo
(
DBG_MODULE
*
module
,
HANDLE
hFile
,
void
*
_nth
,
unsigned
long
nth_ofs
)
{
BOOL
retv
=
FALSE
;
enum
DbgInfoLoad
dil
=
DIL_ERROR
;
PIMAGE_NT_HEADERS
nth
=
(
PIMAGE_NT_HEADERS
)
_nth
;
PIMAGE_DATA_DIRECTORY
dir
=
nth
->
OptionalHeader
.
DataDirectory
+
IMAGE_DIRECTORY_ENTRY_DEBUG
;
PIMAGE_DEBUG_DIRECTORY
dbg
=
NULL
;
...
...
@@ -2932,7 +2960,7 @@ int DEBUG_RegisterMSCDebugInfo( DBG_MODULE *module, HANDLE hFile,
/* Read in section data */
MSC_INFO
(
module
)
=
&
extra_info
;
module
->
msc_info
=
&
extra_info
;
extra_info
.
nsect
=
nth
->
FileHeader
.
NumberOfSections
;
extra_info
.
sectp
=
DBG_alloc
(
extra_info
.
nsect
*
sizeof
(
IMAGE_SECTION_HEADER
)
);
if
(
!
extra_info
.
sectp
)
...
...
@@ -2982,24 +3010,23 @@ int DEBUG_RegisterMSCDebugInfo( DBG_MODULE *module, HANDLE hFile,
goto
leave
;
}
retv
=
DEBUG_ProcessDBGFile
(
module
,
misc
->
Data
,
nth
->
FileHeader
.
TimeDateStamp
);
dil
=
DEBUG_ProcessDBGFile
(
module
,
misc
->
Data
,
nth
->
FileHeader
.
TimeDateStamp
);
}
else
{
/* Debug info is embedded into PE module */
retv
=
DEBUG_ProcessDebugDirectory
(
module
,
file_map
,
dbg
,
nDbg
);
dil
=
DEBUG_ProcessDebugDirectory
(
module
,
file_map
,
dbg
,
nDbg
);
}
leave:
module
->
status
=
retv
?
DM_STATUS_LOADED
:
DM_STATUS_ERROR
;
MSC_INFO
(
module
)
=
NULL
;
module
->
msc_info
=
NULL
;
DEBUG_UnmapDebugInfoFile
(
0
,
hMap
,
file_map
);
if
(
extra_info
.
sectp
)
DBG_free
(
extra_info
.
sectp
);
if
(
dbg
)
DBG_free
(
dbg
);
return
retv
;
return
dil
;
}
...
...
@@ -3007,14 +3034,15 @@ int DEBUG_RegisterMSCDebugInfo( DBG_MODULE *module, HANDLE hFile,
* look for stabs information in PE header (it's how mingw compiler provides its
* debugging information), and also wine PE <-> ELF linking thru .wsolnk sections
*/
int
DEBUG_RegisterStabsDebugInfo
(
DBG_MODULE
*
module
,
HANDLE
hFile
,
void
*
_nth
,
unsigned
long
nth_ofs
)
enum
DbgInfoLoad
DEBUG_RegisterStabsDebugInfo
(
DBG_MODULE
*
module
,
HANDLE
hFile
,
void
*
_nth
,
unsigned
long
nth_ofs
)
{
IMAGE_SECTION_HEADER
pe_seg
;
unsigned
long
pe_seg_ofs
;
int
i
,
stabsize
=
0
,
stabstrsize
=
0
;
unsigned
int
stabs
=
0
,
stabstr
=
0
;
PIMAGE_NT_HEADERS
nth
=
(
PIMAGE_NT_HEADERS
)
_nth
;
enum
DbgInfoLoad
dil
=
DIL_ERROR
;
pe_seg_ofs
=
nth_ofs
+
OFFSET_OF
(
IMAGE_NT_HEADERS
,
OptionalHeader
)
+
nth
->
FileHeader
.
SizeOfOptionalHeader
;
...
...
@@ -3040,7 +3068,7 @@ int DEBUG_RegisterStabsDebugInfo(DBG_MODULE* module, HANDLE hFile, void* _nth,
if
(
DEBUG_READ_MEM_VERBOSE
((
char
*
)
module
->
load_addr
+
stabs
,
s1
,
stabsize
)
&&
DEBUG_READ_MEM_VERBOSE
((
char
*
)
module
->
load_addr
+
stabstr
,
s1
+
stabsize
,
stabstrsize
))
{
DEBUG_ParseStabs
(
s1
,
0
,
0
,
stabsize
,
stabsize
,
stabstrsize
);
dil
=
DEBUG_ParseStabs
(
s1
,
0
,
0
,
stabsize
,
stabsize
,
stabstrsize
);
}
else
{
DEBUG_Printf
(
DBG_CHN_MESG
,
"couldn't read data block
\n
"
);
}
...
...
@@ -3049,7 +3077,9 @@ int DEBUG_RegisterStabsDebugInfo(DBG_MODULE* module, HANDLE hFile, void* _nth,
DEBUG_Printf
(
DBG_CHN_MESG
,
"couldn't alloc %d bytes
\n
"
,
stabsize
+
stabstrsize
);
}
}
else
{
dil
=
DIL_NOINFO
;
}
return
TRUE
;
return
dil
;
}
debugger/stabs.c
View file @
e939206f
/* -*- tab-width: 8; c-basic-offset:
2
-*- */
/* -*- tab-width: 8; c-basic-offset:
4
-*- */
/*
* File stabs.c - read stabs information from the wine executable itself.
...
...
@@ -73,6 +73,9 @@
#define N_EXCL 0xc2
#define N_RBRAC 0xe0
typedef
struct
tagELF_DBG_INFO
{
unsigned
long
elf_addr
;
}
ELF_DBG_INFO
;
struct
stab_nlist
{
union
{
...
...
@@ -767,10 +770,9 @@ DEBUG_ParseStabType(const char * stab)
return
*
DEBUG_ReadTypeEnum
(
&
c
);
}
int
DEBUG_ParseStabs
(
char
*
addr
,
unsigned
int
load_offset
,
unsigned
int
staboff
,
int
stablen
,
unsigned
int
strtaboff
,
int
strtablen
)
enum
DbgInfoLoad
DEBUG_ParseStabs
(
char
*
addr
,
unsigned
int
load_offset
,
unsigned
int
staboff
,
int
stablen
,
unsigned
int
strtaboff
,
int
strtablen
)
{
struct
name_hash
*
curr_func
=
NULL
;
struct
wine_locals
*
curr_loc
=
NULL
;
...
...
@@ -979,8 +981,13 @@ DEBUG_ParseStabs(char * addr, unsigned int load_offset,
* all of the pages related to the stabs, and that
* sucks up swap space like crazy.
*/
#ifdef __ELF__
curr_func
=
DEBUG_AddSymbol
(
symname
,
&
new_value
,
currpath
,
SYM_WINE
|
SYM_FUNC
|
SYM_INVALID
);
#else
curr_func
=
DEBUG_AddSymbol
(
symname
,
&
new_value
,
currpath
,
SYM_WINE
|
SYM_FUNC
|
SYM_INVALID
);
SYM_WINE
|
SYM_FUNC
);
#endif
}
else
{
...
...
@@ -1069,7 +1076,7 @@ DEBUG_ParseStabs(char * addr, unsigned int load_offset,
*/
break
;
default:
DEBUG_Printf
(
DBG_CHN_MESG
,
"Unkown stab type 0x%02x
\n
"
,
stab_ptr
->
n_type
);
DEBUG_Printf
(
DBG_CHN_MESG
,
"Unk
n
own stab type 0x%02x
\n
"
,
stab_ptr
->
n_type
);
break
;
}
...
...
@@ -1088,7 +1095,7 @@ DEBUG_ParseStabs(char * addr, unsigned int load_offset,
curr_types
=
NULL
;
allocated_types
=
0
;
return
TRUE
;
return
DIL_LOADED
;
}
#ifdef __ELF__
...
...
@@ -1102,10 +1109,9 @@ DEBUG_ParseStabs(char * addr, unsigned int load_offset,
* This is all really quite easy, since we don't have to worry about line
* numbers or local data variables.
*/
static
int
DEBUG_ProcessElfSymtab
(
char
*
addr
,
unsigned
int
load_offset
,
Elf32_Shdr
*
symtab
,
Elf32_Shdr
*
strtab
)
static
int
DEBUG_ProcessElfSymtab
(
DBG_MODULE
*
module
,
char
*
addr
,
u_long
load_addr
,
Elf32_Shdr
*
symtab
,
Elf32_Shdr
*
strtab
)
{
char
*
curfile
=
NULL
;
struct
name_hash
*
curr_sym
=
NULL
;
...
...
@@ -1117,7 +1123,6 @@ DEBUG_ProcessElfSymtab(char * addr, unsigned int load_offset,
char
*
symname
;
Elf32_Sym
*
symp
;
symp
=
(
Elf32_Sym
*
)
(
addr
+
symtab
->
sh_offset
);
nsym
=
symtab
->
sh_size
/
sizeof
(
*
symp
);
strp
=
(
char
*
)
(
addr
+
strtab
->
sh_offset
);
...
...
@@ -1154,12 +1159,12 @@ DEBUG_ProcessElfSymtab(char * addr, unsigned int load_offset,
* multiple local symbols by the same name.
*/
if
(
(
DEBUG_GetSymbolValue
(
symname
,
-
1
,
&
new_value
,
FALSE
)
==
TRUE
)
&&
(
new_value
.
addr
.
off
==
(
load_
offset
+
symp
->
st_value
))
)
&&
(
new_value
.
addr
.
off
==
(
load_
addr
+
symp
->
st_value
))
)
continue
;
new_value
.
addr
.
seg
=
0
;
new_value
.
type
=
NULL
;
new_value
.
addr
.
off
=
load_
offset
+
symp
->
st_value
;
new_value
.
addr
.
off
=
load_
addr
+
symp
->
st_value
;
new_value
.
cookie
=
DV_TARGET
;
flags
=
SYM_WINE
|
((
ELF32_ST_TYPE
(
symp
->
st_info
)
==
STT_FUNC
)
?
SYM_FUNC
:
SYM_DATA
);
...
...
@@ -1189,179 +1194,279 @@ DEBUG_ProcessElfSymtab(char * addr, unsigned int load_offset,
* read or parsed)
* 1 on success
*/
static
int
DEBUG_ProcessElfFile
(
const
char
*
filename
,
unsigned
int
load_offset
)
enum
DbgInfoLoad
DEBUG_LoadElfStabs
(
DBG_MODULE
*
module
)
{
int
rtn
=
-
1
;
char
*
addr
=
(
char
*
)
0xffffffff
;
int
fd
=
-
1
;
struct
stat
statbuf
;
Elf32_Ehdr
*
ehptr
;
Elf32_Shdr
*
spnt
;
char
*
shstrtab
;
int
nsect
;
int
i
;
int
stabsect
;
int
stabstrsect
;
/* check that the file exists, and that the module hasn't been loaded yet */
if
(
stat
(
filename
,
&
statbuf
)
==
-
1
)
goto
leave
;
/*
* Now open the file, so that we can mmap() it.
*/
if
((
fd
=
open
(
filename
,
O_RDONLY
))
==
-
1
)
goto
leave
;
rtn
=
0
;
/*
* Now mmap() the file.
*/
addr
=
mmap
(
0
,
statbuf
.
st_size
,
PROT_READ
,
MAP_PRIVATE
,
fd
,
0
);
if
(
addr
==
(
char
*
)
0xffffffff
)
goto
leave
;
/*
* Next, we need to find a few of the internal ELF headers within
* this thing. We need the main executable header, and the section
* table.
*/
ehptr
=
(
Elf32_Ehdr
*
)
addr
;
DEBUG_RegisterELFModule
((
load_offset
==
0
)
?
ehptr
->
e_entry
:
load_offset
,
filename
);
spnt
=
(
Elf32_Shdr
*
)
(
addr
+
ehptr
->
e_shoff
);
nsect
=
ehptr
->
e_shnum
;
shstrtab
=
(
addr
+
spnt
[
ehptr
->
e_shstrndx
].
sh_offset
);
stabsect
=
stabstrsect
=
-
1
;
for
(
i
=
0
;
i
<
nsect
;
i
++
)
{
if
(
strcmp
(
shstrtab
+
spnt
[
i
].
sh_name
,
".stab"
)
==
0
)
stabsect
=
i
;
if
(
strcmp
(
shstrtab
+
spnt
[
i
].
sh_name
,
".stabstr"
)
==
0
)
stabstrsect
=
i
;
}
enum
DbgInfoLoad
dil
=
DIL_ERROR
;
char
*
addr
=
(
char
*
)
0xffffffff
;
int
fd
=
-
1
;
struct
stat
statbuf
;
Elf32_Ehdr
*
ehptr
;
Elf32_Shdr
*
spnt
;
char
*
shstrtab
;
int
i
;
int
stabsect
;
int
stabstrsect
;
if
(
module
->
type
!=
DMT_ELF
||
!
module
->
elf_info
)
{
DEBUG_Printf
(
DBG_CHN_ERR
,
"Bad elf module '%s'
\n
"
,
module
->
module_name
);
return
DIL_ERROR
;
}
if
(
stabsect
==
-
1
||
stabstrsect
==
-
1
)
{
DEBUG_Printf
(
DBG_CHN_WARN
,
"no .stab section
\n
"
);
goto
leave
;
}
/* check that the file exists, and that the module hasn't been loaded yet */
if
(
stat
(
module
->
module_name
,
&
statbuf
)
==
-
1
)
goto
leave
;
/*
* Now open the file, so that we can mmap() it.
*/
if
((
fd
=
open
(
module
->
module_name
,
O_RDONLY
))
==
-
1
)
goto
leave
;
dil
=
DIL_NOINFO
;
/*
* Now mmap() the file.
*/
addr
=
mmap
(
0
,
statbuf
.
st_size
,
PROT_READ
,
MAP_PRIVATE
,
fd
,
0
);
if
(
addr
==
(
char
*
)
0xffffffff
)
goto
leave
;
/*
* Next, we need to find a few of the internal ELF headers within
* this thing. We need the main executable header, and the section
* table.
*/
ehptr
=
(
Elf32_Ehdr
*
)
addr
;
spnt
=
(
Elf32_Shdr
*
)
(
addr
+
ehptr
->
e_shoff
);
shstrtab
=
(
addr
+
spnt
[
ehptr
->
e_shstrndx
].
sh_offset
);
stabsect
=
stabstrsect
=
-
1
;
for
(
i
=
0
;
i
<
ehptr
->
e_shnum
;
i
++
)
{
if
(
strcmp
(
shstrtab
+
spnt
[
i
].
sh_name
,
".stab"
)
==
0
)
stabsect
=
i
;
if
(
strcmp
(
shstrtab
+
spnt
[
i
].
sh_name
,
".stabstr"
)
==
0
)
stabstrsect
=
i
;
}
if
(
stabsect
==
-
1
||
stabstrsect
==
-
1
)
{
DEBUG_Printf
(
DBG_CHN_WARN
,
"no .stab section
\n
"
);
goto
leave
;
}
/*
* OK, now just parse all of the stabs.
*/
if
(
DEBUG_ParseStabs
(
addr
,
module
->
elf_info
->
elf_addr
,
spnt
[
stabsect
].
sh_offset
,
spnt
[
stabsect
].
sh_size
,
spnt
[
stabstrsect
].
sh_offset
,
spnt
[
stabstrsect
].
sh_size
))
{
dil
=
DIL_LOADED
;
}
else
{
dil
=
DIL_ERROR
;
DEBUG_Printf
(
DBG_CHN_WARN
,
"bad stabs
\n
"
);
goto
leave
;
}
for
(
i
=
0
;
i
<
ehptr
->
e_shnum
;
i
++
)
{
if
(
(
strcmp
(
shstrtab
+
spnt
[
i
].
sh_name
,
".symtab"
)
==
0
)
&&
(
spnt
[
i
].
sh_type
==
SHT_SYMTAB
))
DEBUG_ProcessElfSymtab
(
module
,
addr
,
module
->
elf_info
->
elf_addr
,
spnt
+
i
,
spnt
+
spnt
[
i
].
sh_link
);
if
(
(
strcmp
(
shstrtab
+
spnt
[
i
].
sh_name
,
".dynsym"
)
==
0
)
&&
(
spnt
[
i
].
sh_type
==
SHT_DYNSYM
))
DEBUG_ProcessElfSymtab
(
module
,
addr
,
module
->
elf_info
->
elf_addr
,
spnt
+
i
,
spnt
+
spnt
[
i
].
sh_link
);
}
/*
* OK, now just parse all of the stabs.
*/
if
(
!
(
rtn
=
DEBUG_ParseStabs
(
addr
,
load_offset
,
spnt
[
stabsect
].
sh_offset
,
spnt
[
stabsect
].
sh_size
,
spnt
[
stabstrsect
].
sh_offset
,
spnt
[
stabstrsect
].
sh_size
)))
{
DEBUG_Printf
(
DBG_CHN_WARN
,
"bad stabs
\n
"
);
goto
leave
;
}
for
(
i
=
0
;
i
<
nsect
;
i
++
)
{
if
(
(
strcmp
(
shstrtab
+
spnt
[
i
].
sh_name
,
".symtab"
)
==
0
)
&&
(
spnt
[
i
].
sh_type
==
SHT_SYMTAB
))
DEBUG_ProcessElfSymtab
(
addr
,
load_offset
,
spnt
+
i
,
spnt
+
spnt
[
i
].
sh_link
);
if
(
(
strcmp
(
shstrtab
+
spnt
[
i
].
sh_name
,
".dynsym"
)
==
0
)
&&
(
spnt
[
i
].
sh_type
==
SHT_DYNSYM
))
DEBUG_ProcessElfSymtab
(
addr
,
load_offset
,
spnt
+
i
,
spnt
+
spnt
[
i
].
sh_link
);
}
leave:
if
(
addr
!=
(
char
*
)
0xffffffff
)
munmap
(
addr
,
statbuf
.
st_size
);
if
(
fd
!=
-
1
)
close
(
fd
);
return
rtn
;
leave:
if
(
addr
!=
(
char
*
)
0xffffffff
)
munmap
(
addr
,
statbuf
.
st_size
);
if
(
fd
!=
-
1
)
close
(
fd
);
return
dil
;
}
static
int
DEBUG_ProcessElfFileFromPath
(
const
char
*
filename
,
unsigned
int
load_offset
,
const
char
*
path
)
/*
* Loads the information for ELF module stored in 'filename'
* the module has been loaded at 'load_offset' address
* returns
* -1 if the file cannot be found/opened
* 0 if the file doesn't contain symbolic info (or this info cannot be
* read or parsed)
* 1 on success
*/
static
enum
DbgInfoLoad
DEBUG_ProcessElfFile
(
const
char
*
filename
,
unsigned
int
load_offset
,
unsigned
int
*
dyn_addr
)
{
int
rtn
=
-
1
;
char
*
s
,
*
t
,
*
fn
;
char
*
paths
=
NULL
;
if
(
!
path
)
return
-
1
;
for
(
s
=
paths
=
DBG_strdup
(
path
);
s
&&
*
s
;
s
=
(
t
)
?
(
t
+
1
)
:
NULL
)
{
t
=
strchr
(
s
,
':'
);
if
(
t
)
*
t
=
'\0'
;
fn
=
(
char
*
)
DBG_alloc
(
strlen
(
filename
)
+
1
+
strlen
(
s
)
+
1
);
if
(
!
fn
)
break
;
strcpy
(
fn
,
s
);
strcat
(
fn
,
"/"
);
strcat
(
fn
,
filename
);
rtn
=
DEBUG_ProcessElfFile
(
fn
,
load_offset
);
DBG_free
(
fn
);
if
(
rtn
>=
0
)
break
;
s
=
(
t
)
?
(
t
+
1
)
:
NULL
;
}
enum
DbgInfoLoad
dil
=
DIL_ERROR
;
char
*
addr
=
(
char
*
)
0xffffffff
;
int
fd
=
-
1
;
struct
stat
statbuf
;
Elf32_Ehdr
*
ehptr
;
Elf32_Shdr
*
spnt
;
Elf32_Phdr
*
ppnt
;
char
*
shstrtab
;
int
i
;
DBG_MODULE
*
module
=
NULL
;
DWORD
size
;
DWORD
delta
;
DEBUG_Printf
(
DBG_CHN_TRACE
,
"Processing elf file '%s'
\n
"
,
filename
);
/* check that the file exists, and that the module hasn't been loaded yet */
if
(
stat
(
filename
,
&
statbuf
)
==
-
1
)
goto
leave
;
/*
* Now open the file, so that we can mmap() it.
*/
if
((
fd
=
open
(
filename
,
O_RDONLY
))
==
-
1
)
goto
leave
;
/*
* Now mmap() the file.
*/
addr
=
mmap
(
0
,
statbuf
.
st_size
,
PROT_READ
,
MAP_PRIVATE
,
fd
,
0
);
if
(
addr
==
(
char
*
)
0xffffffff
)
goto
leave
;
dil
=
DIL_NOINFO
;
/*
* Next, we need to find a few of the internal ELF headers within
* this thing. We need the main executable header, and the section
* table.
*/
ehptr
=
(
Elf32_Ehdr
*
)
addr
;
spnt
=
(
Elf32_Shdr
*
)
(
addr
+
ehptr
->
e_shoff
);
shstrtab
=
(
addr
+
spnt
[
ehptr
->
e_shstrndx
].
sh_offset
);
/* if non relocatable ELF, then remove fixed address from computation
* otherwise, all addresses are zero based
*/
delta
=
(
load_offset
==
0
)
?
ehptr
->
e_entry
:
0
;
/* grab size of module once loaded in memory */
ppnt
=
(
Elf32_Phdr
*
)
(
addr
+
ehptr
->
e_phoff
);
size
=
0
;
for
(
i
=
0
;
i
<
ehptr
->
e_phnum
;
i
++
)
{
if
(
ppnt
[
i
].
p_type
!=
PT_LOAD
)
continue
;
if
(
size
<
ppnt
[
i
].
p_vaddr
-
delta
+
ppnt
[
i
].
p_memsz
)
size
=
ppnt
[
i
].
p_vaddr
-
delta
+
ppnt
[
i
].
p_memsz
;
}
for
(
i
=
0
;
i
<
ehptr
->
e_shnum
;
i
++
)
{
if
(
strcmp
(
shstrtab
+
spnt
[
i
].
sh_name
,
".bss"
)
==
0
&&
spnt
[
i
].
sh_type
==
SHT_NOBITS
)
{
if
(
size
<
spnt
[
i
].
sh_addr
-
delta
+
spnt
[
i
].
sh_size
)
size
=
spnt
[
i
].
sh_addr
-
delta
+
spnt
[
i
].
sh_size
;
}
if
(
strcmp
(
shstrtab
+
spnt
[
i
].
sh_name
,
".dynamic"
)
==
0
&&
spnt
[
i
].
sh_type
==
SHT_DYNAMIC
)
{
if
(
dyn_addr
)
*
dyn_addr
=
spnt
[
i
].
sh_addr
;
}
}
module
=
DEBUG_RegisterELFModule
((
load_offset
==
0
)
?
ehptr
->
e_entry
:
load_offset
,
size
,
filename
);
if
(
!
module
)
{
dil
=
DIL_ERROR
;
goto
leave
;
}
if
((
module
->
elf_info
=
DBG_alloc
(
sizeof
(
ELF_DBG_INFO
)))
==
NULL
)
{
DEBUG_Printf
(
DBG_CHN_ERR
,
"OOM
\n
"
);
exit
(
0
);
}
module
->
elf_info
->
elf_addr
=
load_offset
;
dil
=
DEBUG_LoadElfStabs
(
module
);
DBG_free
(
paths
);
return
rtn
;
leave:
if
(
addr
!=
(
char
*
)
0xffffffff
)
munmap
(
addr
,
statbuf
.
st_size
);
if
(
fd
!=
-
1
)
close
(
fd
);
if
(
module
)
module
->
dil
=
dil
;
return
dil
;
}
static
int
DEBUG_ProcessElfObject
(
const
char
*
filename
,
unsigned
int
load_offset
)
static
enum
DbgInfoLoad
DEBUG_ProcessElfFileFromPath
(
const
char
*
filename
,
unsigned
int
load_offset
,
unsigned
int
*
dyn_addr
,
const
char
*
path
)
{
int
rtn
=
-
1
;
const
char
*
fmt
;
enum
DbgInfoLoad
dil
=
DIL_ERROR
;
char
*
s
,
*
t
,
*
fn
;
char
*
paths
=
NULL
;
if
(
!
path
)
return
-
1
;
for
(
s
=
paths
=
DBG_strdup
(
path
);
s
&&
*
s
;
s
=
(
t
)
?
(
t
+
1
)
:
NULL
)
{
t
=
strchr
(
s
,
':'
);
if
(
t
)
*
t
=
'\0'
;
fn
=
(
char
*
)
DBG_alloc
(
strlen
(
filename
)
+
1
+
strlen
(
s
)
+
1
);
if
(
!
fn
)
break
;
strcpy
(
fn
,
s
);
strcat
(
fn
,
"/"
);
strcat
(
fn
,
filename
);
dil
=
DEBUG_ProcessElfFile
(
fn
,
load_offset
,
dyn_addr
);
DBG_free
(
fn
);
if
(
dil
!=
DIL_ERROR
)
break
;
s
=
(
t
)
?
(
t
+
1
)
:
NULL
;
}
DEBUG_Printf
(
DBG_CHN_TRACE
,
"Processing elf file '%s'
\n
"
,
filename
);
DBG_free
(
paths
);
return
dil
;
}
if
(
filename
==
NULL
)
return
FALSE
;
if
(
DEBUG_FindModuleByName
(
filename
,
DM_TYPE_ELF
))
return
TRUE
;
static
enum
DbgInfoLoad
DEBUG_ProcessElfObject
(
const
char
*
filename
,
unsigned
int
load_offset
,
unsigned
int
*
dyn_addr
)
{
enum
DbgInfoLoad
dil
=
DIL_ERROR
;
if
(
filename
==
NULL
)
return
DIL_ERROR
;
if
(
DEBUG_FindModuleByName
(
filename
,
DMT_ELF
))
return
DIL_LOADED
;
rtn
=
DEBUG_ProcessElfFile
(
filename
,
load_offset
);
dil
=
DEBUG_ProcessElfFile
(
filename
,
load_offset
,
dyn_addr
);
/* if relative pathname, try some absolute base dirs */
if
(
rtn
<
0
&&
!
strchr
(
filename
,
'/'
))
{
rtn
=
DEBUG_ProcessElfFileFromPath
(
filename
,
load_offset
,
getenv
(
"PATH"
));
if
(
rtn
<
0
)
rtn
=
DEBUG_ProcessElfFileFromPath
(
filename
,
load_offset
,
getenv
(
"LD_LIBRARY_PATH"
));
if
(
dil
==
DIL_ERROR
&&
!
strchr
(
filename
,
'/'
))
{
dil
=
DEBUG_ProcessElfFileFromPath
(
filename
,
load_offset
,
dyn_addr
,
getenv
(
"PATH"
));
if
(
dil
==
DIL_ERROR
)
dil
=
DEBUG_ProcessElfFileFromPath
(
filename
,
load_offset
,
dyn_addr
,
getenv
(
"LD_LIBRARY_PATH"
));
}
switch
(
rtn
)
{
case
1
:
fmt
=
"Loaded stabs debug symbols from ELF '%s' (0x%08x)
\n
"
;
break
;
case
0
:
fmt
=
"No stabs debug symbols in ELF '%s' (0x%08x)
\n
"
;
break
;
case
-
1
:
fmt
=
"Can't find file for ELF '%s' (0x%08x)
\n
"
;
break
;
default:
DEBUG_Printf
(
DBG_CHN_ERR
,
"Oooocch (%d)
\n
"
,
rtn
);
return
FALSE
;
}
DEBUG_Printf
(
DBG_CHN_MESG
,
fmt
,
filename
,
load_offset
);
DEBUG_ReportDIL
(
dil
,
"ELF"
,
filename
,
load_offset
);
return
rtn
>=
0
;
return
dil
;
}
static
BOOL
DEBUG_WalkList
(
struct
r_debug
*
dbg_hdr
)
{
u_long
lm_addr
;
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
* cases the first entry doesn't appear with a name, in other cases it
* does.
*/
for
(
lm_addr
=
(
u_long
)
dbg_hdr
->
r_map
;
lm_addr
;
lm_addr
=
(
u_long
)
lm
.
l_next
)
{
if
(
!
DEBUG_READ_MEM_VERBOSE
((
void
*
)
lm_addr
,
&
lm
,
sizeof
(
lm
)))
return
FALSE
;
if
(
lm
.
l_addr
!=
0
&&
DEBUG_READ_MEM_VERBOSE
((
void
*
)
lm
.
l_addr
,
&
ehdr
,
sizeof
(
ehdr
))
&&
ehdr
.
e_type
==
ET_DYN
&&
/* only look at dynamic modules */
lm
.
l_name
!=
NULL
&&
DEBUG_READ_MEM_VERBOSE
((
void
*
)
lm
.
l_name
,
bufstr
,
sizeof
(
bufstr
)))
{
bufstr
[
sizeof
(
bufstr
)
-
1
]
=
'\0'
;
DEBUG_ProcessElfObject
(
bufstr
,
(
unsigned
)
lm
.
l_addr
);
u_long
lm_addr
;
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
* cases the first entry doesn't appear with a name, in other cases it
* does.
*/
for
(
lm_addr
=
(
u_long
)
dbg_hdr
->
r_map
;
lm_addr
;
lm_addr
=
(
u_long
)
lm
.
l_next
)
{
if
(
!
DEBUG_READ_MEM_VERBOSE
((
void
*
)
lm_addr
,
&
lm
,
sizeof
(
lm
)))
return
FALSE
;
if
(
lm
.
l_addr
!=
0
&&
DEBUG_READ_MEM_VERBOSE
((
void
*
)
lm
.
l_addr
,
&
ehdr
,
sizeof
(
ehdr
))
&&
ehdr
.
e_type
==
ET_DYN
&&
/* only look at dynamic modules */
lm
.
l_name
!=
NULL
&&
DEBUG_READ_MEM_VERBOSE
((
void
*
)
lm
.
l_name
,
bufstr
,
sizeof
(
bufstr
)))
{
bufstr
[
sizeof
(
bufstr
)
-
1
]
=
'\0'
;
DEBUG_ProcessElfObject
(
bufstr
,
(
unsigned
)
lm
.
l_addr
,
NULL
);
}
}
}
return
TRUE
;
return
TRUE
;
}
static
BOOL
DEBUG_RescanElf
(
void
)
...
...
@@ -1379,75 +1484,65 @@ static BOOL DEBUG_RescanElf(void)
case
RT_ADD
:
break
;
case
RT_DELETE
:
/*FIXME: this is not currently handled, would need some kind of mark&sweep algo */
/*
FIXME: this is not currently handled, would need some kind of mark&sweep algo */
break
;
}
return
FALSE
;
}
int
DEBUG_ReadExecutableDbgInfo
(
const
char
*
exe_name
)
enum
DbgInfoLoad
DEBUG_ReadExecutableDbgInfo
(
const
char
*
exe_name
)
{
Elf32_Dyn
dyn
;
struct
r_debug
dbg_hdr
;
int
rtn
=
FALSE
;
DBG_VALUE
val
;
/*
* Make sure we can stat and open this file.
*/
if
(
exe_name
==
NULL
)
goto
leave
;
DEBUG_ProcessElfObject
(
exe_name
,
0
);
/* previous step should have loaded symbol _DYNAMIC if it exists inside
* the main executable
*/
if
(
!
DEBUG_GetSymbolValue
(
"_DYNAMIC"
,
-
1
,
&
val
,
FALSE
))
{
DEBUG_Printf
(
DBG_CHN_WARN
,
"Can't find symbol _DYNAMIC
\n
"
);
goto
leave
;
}
do
{
if
(
!
DEBUG_READ_MEM_VERBOSE
((
void
*
)
val
.
addr
.
off
,
&
dyn
,
sizeof
(
dyn
)))
goto
leave
;
val
.
addr
.
off
+=
sizeof
(
dyn
);
}
while
(
dyn
.
d_tag
!=
DT_DEBUG
&&
dyn
.
d_tag
!=
DT_NULL
);
if
(
dyn
.
d_tag
==
DT_NULL
)
goto
leave
;
/*
* OK, now dig into the actual tables themselves.
*/
if
(
!
DEBUG_READ_MEM_VERBOSE
((
void
*
)
dyn
.
d_un
.
d_ptr
,
&
dbg_hdr
,
sizeof
(
dbg_hdr
)))
goto
leave
;
assert
(
!
DEBUG_CurrProcess
->
dbg_hdr_addr
);
DEBUG_CurrProcess
->
dbg_hdr_addr
=
(
u_long
)
dyn
.
d_un
.
d_ptr
;
if
(
dbg_hdr
.
r_brk
)
{
DBG_VALUE
value
;
DEBUG_Printf
(
DBG_CHN_TRACE
,
"Setting up a breakpoint on r_brk(%lx)
\n
"
,
(
unsigned
long
)
dbg_hdr
.
r_brk
);
DEBUG_SetBreakpoints
(
FALSE
);
value
.
type
=
NULL
;
value
.
cookie
=
DV_TARGET
;
value
.
addr
.
seg
=
0
;
value
.
addr
.
off
=
(
DWORD
)
dbg_hdr
.
r_brk
;
DEBUG_AddBreakpoint
(
&
value
,
DEBUG_RescanElf
);
DEBUG_SetBreakpoints
(
TRUE
);
}
rtn
=
DEBUG_WalkList
(
&
dbg_hdr
);
leave:
return
rtn
;
Elf32_Dyn
dyn
;
struct
r_debug
dbg_hdr
;
enum
DbgInfoLoad
dil
=
DIL_NOINFO
;
unsigned
int
dyn_addr
;
/*
* Make sure we can stat and open this file.
*/
if
(
exe_name
==
NULL
)
goto
leave
;
DEBUG_ProcessElfObject
(
exe_name
,
0
,
&
dyn_addr
);
do
{
if
(
!
DEBUG_READ_MEM_VERBOSE
((
void
*
)
dyn_addr
,
&
dyn
,
sizeof
(
dyn
)))
goto
leave
;
dyn_addr
+=
sizeof
(
dyn
);
}
while
(
dyn
.
d_tag
!=
DT_DEBUG
&&
dyn
.
d_tag
!=
DT_NULL
);
if
(
dyn
.
d_tag
==
DT_NULL
)
goto
leave
;
/*
* OK, now dig into the actual tables themselves.
*/
if
(
!
DEBUG_READ_MEM_VERBOSE
((
void
*
)
dyn
.
d_un
.
d_ptr
,
&
dbg_hdr
,
sizeof
(
dbg_hdr
)))
goto
leave
;
assert
(
!
DEBUG_CurrProcess
->
dbg_hdr_addr
);
DEBUG_CurrProcess
->
dbg_hdr_addr
=
(
u_long
)
dyn
.
d_un
.
d_ptr
;
if
(
dbg_hdr
.
r_brk
)
{
DBG_VALUE
value
;
DEBUG_Printf
(
DBG_CHN_TRACE
,
"Setting up a breakpoint on r_brk(%lx)
\n
"
,
(
unsigned
long
)
dbg_hdr
.
r_brk
);
DEBUG_SetBreakpoints
(
FALSE
);
value
.
type
=
NULL
;
value
.
cookie
=
DV_TARGET
;
value
.
addr
.
seg
=
0
;
value
.
addr
.
off
=
(
DWORD
)
dbg_hdr
.
r_brk
;
DEBUG_AddBreakpoint
(
&
value
,
DEBUG_RescanElf
);
DEBUG_SetBreakpoints
(
TRUE
);
}
dil
=
DEBUG_WalkList
(
&
dbg_hdr
);
leave:
return
dil
;
}
#else
/* !__ELF__ */
int
DEBUG_ReadExecutableDbgInfo
(
const
char
*
exe_name
)
int
DEBUG_ReadExecutableDbgInfo
(
const
char
*
exe_name
)
{
return
FALSE
;
}
...
...
debugger/winedbg.c
View file @
e939206f
...
...
@@ -145,6 +145,7 @@ static DBG_PROCESS* DEBUG_AddProcess(DWORD pid, HANDLE h)
p
->
num_threads
=
0
;
p
->
continue_on_first_exception
=
FALSE
;
p
->
modules
=
NULL
;
p
->
num_modules
=
0
;
p
->
next_index
=
0
;
p
->
dbg_hdr_addr
=
0
;
...
...
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