Commit 084e74bd authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

- Added experimental parsing for C++ code (but winedbg doesn't support

C++ ABI). - Now loading symbols for included files.
parent 27441a91
...@@ -344,13 +344,54 @@ static int DEBUG_PTS_ReadRange(struct ParseTypedefData* ptd, struct datatype** d ...@@ -344,13 +344,54 @@ static int DEBUG_PTS_ReadRange(struct ParseTypedefData* ptd, struct datatype** d
return 0; return 0;
} }
static inline int DEBUG_PTS_ReadAggregate(struct ParseTypedefData* ptd, struct datatype* sdt) static inline int DEBUG_PTS_ReadMethodInfo(struct ParseTypedefData* ptd,
struct datatype* dt)
{
char* tmp;
if (*ptd->ptr++ == ':')
{
if (!(tmp = strchr(ptd->ptr, ';'))) return -1;
ptd->ptr = tmp + 1;
}
if (!(*ptd->ptr >= '0' && *ptd->ptr <= '9')) return -1;
ptd->ptr++;
if (!(ptd->ptr[0] >= 'A' && *ptd->ptr <= 'D')) return -1;
ptd->ptr++;
if (*ptd->ptr++ != '.') return -1;
if (*ptd->ptr != ';')
{
while (*ptd->ptr)
{
/* some GCC versions (2.96 for example) really spit out wrongly defined
* stabs... in some cases, the methods are not correctly handled
* so just swallow the garbage until either .; (end of method)
* or ;; (end of struct) are found
*/
if (ptd->ptr[0] == '.' && ptd->ptr[1] == ';')
{
ptd->ptr++;
break;
}
if (ptd->ptr[0] == ';' && ptd->ptr[1] == ';')
break;
ptd->ptr++;
}
}
return 0;
}
static inline int DEBUG_PTS_ReadAggregate(struct ParseTypedefData* ptd,
struct datatype* sdt)
{ {
int sz, ofs; int sz, ofs;
char* last; char* last;
struct datatype* adt; struct datatype* adt;
int idx; int idx;
int doadd; int doadd;
BOOL inMethod;
sz = strtol(ptd->ptr, &last, 10); sz = strtol(ptd->ptr, &last, 10);
if (last == ptd->ptr) return -1; if (last == ptd->ptr) return -1;
...@@ -366,29 +407,62 @@ static inline int DEBUG_PTS_ReadAggregate(struct ParseTypedefData* ptd, struct d ...@@ -366,29 +407,62 @@ static inline int DEBUG_PTS_ReadAggregate(struct ParseTypedefData* ptd, struct d
while (*ptd->ptr != ';') { while (*ptd->ptr != ';') {
/* agg_name : type ',' <int:offset> ',' <int:size> */ /* agg_name : type ',' <int:offset> ',' <int:size> */
idx = ptd->idx; idx = ptd->idx;
if (DEBUG_PTS_ReadID(ptd) == -1) return -1; if (DEBUG_PTS_ReadID(ptd) == -1) return -1;
/* Ref. TSDF R2.130 Section 7.4. When the field name is a method name /* Ref. TSDF R2.130 Section 7.4. When the field name is a method name
* it is followed by two colons rather than one. * it is followed by two colons rather than one.
*/ */
if (*ptd->ptr == ':') ptd->ptr++; if (*ptd->ptr == ':')
{
ptd->ptr++;
{
char* psemic = strchr(ptd->ptr, ';');
char* psharp = strchr(ptd->ptr, '#');
if (!psharp || psharp > psemic)
{
struct datatype* dt = NULL;
/* FIXME: hack... this shall be a ctor */
if (DEBUG_PTS_ReadTypedef(ptd, NULL, &dt) == -1) return -1;
if (DEBUG_PTS_ReadMethodInfo(ptd, dt) == -1) return -1;
if (*ptd->ptr++ != ';') return -1;
ptd->idx = idx;
continue;
}
}
inMethod = TRUE;
}
else
{
inMethod = FALSE;
}
if (DEBUG_PTS_ReadTypedef(ptd, NULL, &adt) == -1) return -1; if (DEBUG_PTS_ReadTypedef(ptd, NULL, &adt) == -1) return -1;
if (!adt) return -1; if (!adt) return -1;
if (*ptd->ptr++ != ',') return -1; if (*ptd->ptr != ',')
{
if (!inMethod) return -1;
ptd->ptr++;
}
else
{
ptd->ptr++;
if (DEBUG_PTS_ReadNum(ptd, &ofs) == -1) return -1; if (DEBUG_PTS_ReadNum(ptd, &ofs) == -1) return -1;
if (*ptd->ptr++ != ',') return -1; if (*ptd->ptr++ != ',') return -1;
if (DEBUG_PTS_ReadNum(ptd, &sz) == -1) return -1; if (DEBUG_PTS_ReadNum(ptd, &sz) == -1) return -1;
if (*ptd->ptr++ != ';') return -1; if (*ptd->ptr++ != ';') return -1;
if (doadd) DEBUG_AddStructElement(sdt, ptd->buf + idx, adt, ofs, sz); if (doadd) DEBUG_AddStructElement(sdt, ptd->buf + idx, adt, ofs, sz);
}
ptd->idx = idx; ptd->idx = idx;
} }
ptd->ptr++; /* ';' */ ptd->ptr++; /* ';' */
return 0; return 0;
} }
static inline int DEBUG_PTS_ReadEnum(struct ParseTypedefData* ptd, struct datatype* edt) static inline int DEBUG_PTS_ReadEnum(struct ParseTypedefData* ptd,
struct datatype* edt)
{ {
int ofs; int ofs;
int idx; int idx;
...@@ -405,7 +479,8 @@ static inline int DEBUG_PTS_ReadEnum(struct ParseTypedefData* ptd, struct dataty ...@@ -405,7 +479,8 @@ static inline int DEBUG_PTS_ReadEnum(struct ParseTypedefData* ptd, struct dataty
return 0; return 0;
} }
static inline int DEBUG_PTS_ReadArray(struct ParseTypedefData* ptd, struct datatype* adt) static inline int DEBUG_PTS_ReadArray(struct ParseTypedefData* ptd,
struct datatype* adt)
{ {
int lo, hi; int lo, hi;
struct datatype* rdt; struct datatype* rdt;
...@@ -463,6 +538,7 @@ static int DEBUG_PTS_ReadTypedef(struct ParseTypedefData* ptd, const char* typen ...@@ -463,6 +538,7 @@ static int DEBUG_PTS_ReadTypedef(struct ParseTypedefData* ptd, const char* typen
/* then the real definitions */ /* then the real definitions */
switch (*ptd->ptr++) { switch (*ptd->ptr++) {
case '*': case '*':
case '&':
new_dt = DEBUG_NewDataType(DT_POINTER, NULL); new_dt = DEBUG_NewDataType(DT_POINTER, NULL);
if (DEBUG_PTS_ReadTypedef(ptd, NULL, &ref_dt) == -1) return -1; if (DEBUG_PTS_ReadTypedef(ptd, NULL, &ref_dt) == -1) return -1;
DEBUG_SetPointerType(new_dt, ref_dt); DEBUG_SetPointerType(new_dt, ref_dt);
...@@ -588,7 +664,8 @@ static int DEBUG_PTS_ReadTypedef(struct ParseTypedefData* ptd, const char* typen ...@@ -588,7 +664,8 @@ static int DEBUG_PTS_ReadTypedef(struct ParseTypedefData* ptd, const char* typen
case 31: basic = DT_BASIC_LONGLONGINT; break; case 31: basic = DT_BASIC_LONGLONGINT; break;
case 32: basic = DT_BASIC_ULONGLONGINT; break; case 32: basic = DT_BASIC_ULONGLONGINT; break;
default: default:
DEBUG_Printf(DBG_CHN_MESG, "Unsupported integral type (%d/%d)\n", lo, sz); DEBUG_Printf(DBG_CHN_MESG,
"Unsupported integral type (%d/%d)\n", lo, sz);
return -1; return -1;
} }
if (!(new_dt = DEBUG_GetBasicType(basic))) { if (!(new_dt = DEBUG_GetBasicType(basic))) {
...@@ -598,6 +675,33 @@ static int DEBUG_PTS_ReadTypedef(struct ParseTypedefData* ptd, const char* typen ...@@ -598,6 +675,33 @@ static int DEBUG_PTS_ReadTypedef(struct ParseTypedefData* ptd, const char* typen
if (*ptd->ptr++ != ';') return -1; if (*ptd->ptr++ != ';') return -1;
} }
break; break;
case '#':
new_dt = DEBUG_NewDataType(DT_FUNC, NULL);
if (*ptd->ptr == '#')
{
ptd->ptr++;
if (DEBUG_PTS_ReadTypedef(ptd, NULL, &ref_dt) == -1) return -1;
DEBUG_SetPointerType(new_dt, ref_dt);
if (*ptd->ptr++ != ';') return -1;
}
else
{
struct datatype* cls_dt;
struct datatype* pmt_dt;
if (DEBUG_PTS_ReadTypedef(ptd, NULL, &cls_dt) == -1) return -1;
if (*ptd->ptr++ != ',') return -1;
if (DEBUG_PTS_ReadTypedef(ptd, NULL, &ref_dt) == -1) return -1;
DEBUG_SetPointerType(new_dt, ref_dt);
while (*ptd->ptr++ == ',')
{
if (DEBUG_PTS_ReadTypedef(ptd, NULL, &pmt_dt) == -1) return -1;
}
}
if (DEBUG_PTS_ReadMethodInfo(ptd, new_dt) == -1) return -1;
break;
default: default:
DEBUG_Printf(DBG_CHN_MESG, "Unknown type '%c'\n", ptd->ptr[-1]); DEBUG_Printf(DBG_CHN_MESG, "Unknown type '%c'\n", ptd->ptr[-1]);
return -1; return -1;
...@@ -647,11 +751,13 @@ static int DEBUG_ParseTypedefStab(char* ptr, const char* typename) ...@@ -647,11 +751,13 @@ static int DEBUG_ParseTypedefStab(char* ptr, const char* typename)
if ((ptd.ptr = strchr(ptr, ':'))) { if ((ptd.ptr = strchr(ptr, ':'))) {
ptd.ptr++; ptd.ptr++;
if (*ptd.ptr != '(') ptd.ptr++; if (*ptd.ptr != '(') ptd.ptr++;
/* most of type definitions take one char, except Tt */
if (*ptd.ptr != '(') ptd.ptr++;
ret = DEBUG_PTS_ReadTypedef(&ptd, typename, &dt); ret = DEBUG_PTS_ReadTypedef(&ptd, typename, &dt);
} }
if (ret == -1 || *ptd.ptr) { if (ret == -1 || *ptd.ptr) {
DEBUG_Printf(DBG_CHN_MESG, "failure on %s at %s\n", ptr, ptd.ptr); DEBUG_Printf(DBG_CHN_MESG, "Failure on %s at %s\n", ptr, ptd.ptr);
return FALSE; return FALSE;
} }
...@@ -729,7 +835,7 @@ enum DbgInfoLoad DEBUG_ParseStabs(char * addr, unsigned int load_offset, ...@@ -729,7 +835,7 @@ enum DbgInfoLoad DEBUG_ParseStabs(char * addr, unsigned int load_offset,
strtabinc = 0; strtabinc = 0;
stabbuff[0] = '\0'; stabbuff[0] = '\0';
for(i=0; i < nstab; i++, stab_ptr++ ) for (i = 0; i < nstab; i++, stab_ptr++)
{ {
ptr = strs + (unsigned int) stab_ptr->n_un.n_name; ptr = strs + (unsigned int) stab_ptr->n_un.n_name;
if( ptr[strlen(ptr) - 1] == '\\' ) if( ptr[strlen(ptr) - 1] == '\\' )
...@@ -944,7 +1050,7 @@ enum DbgInfoLoad DEBUG_ParseStabs(char * addr, unsigned int load_offset, ...@@ -944,7 +1050,7 @@ enum DbgInfoLoad DEBUG_ParseStabs(char * addr, unsigned int load_offset,
} }
#endif #endif
if( *ptr == '\0' ) if( *ptr == '\0' ) /* end of N_SO file */
{ {
/* /*
* Nuke old path. * Nuke old path.
...@@ -971,6 +1077,7 @@ enum DbgInfoLoad DEBUG_ParseStabs(char * addr, unsigned int load_offset, ...@@ -971,6 +1077,7 @@ enum DbgInfoLoad DEBUG_ParseStabs(char * addr, unsigned int load_offset,
* ignore it. * ignore it.
*/ */
in_external_file = !(subpath == NULL || strcmp(ptr, subpath) == 0); in_external_file = !(subpath == NULL || strcmp(ptr, subpath) == 0);
in_external_file = FALSE; /* FIXME EPP hack FIXME */;
break; break;
case N_UNDF: case N_UNDF:
strs += strtabinc; strs += strtabinc;
...@@ -1004,7 +1111,7 @@ enum DbgInfoLoad DEBUG_ParseStabs(char * addr, unsigned int load_offset, ...@@ -1004,7 +1111,7 @@ enum DbgInfoLoad DEBUG_ParseStabs(char * addr, unsigned int load_offset,
stabbuff[0] = '\0'; stabbuff[0] = '\0';
#if 0 #if 0
DEBUG_Printf(DBG_CHN_MESG, "%d %x %s\n", stab_ptr->n_type, DEBUG_Printf(DBG_CHN_MESG, "0x%02x %x %s\n", stab_ptr->n_type,
(unsigned int) stab_ptr->n_value, (unsigned int) stab_ptr->n_value,
strs + (unsigned int) stab_ptr->n_un.n_name); strs + (unsigned int) stab_ptr->n_un.n_name);
#endif #endif
...@@ -1044,7 +1151,7 @@ static int DEBUG_ProcessElfSymtab(DBG_MODULE* module, char* addr, ...@@ -1044,7 +1151,7 @@ static int DEBUG_ProcessElfSymtab(DBG_MODULE* module, char* addr,
nsym = symtab->sh_size / sizeof(*symp); nsym = symtab->sh_size / sizeof(*symp);
strp = (char *) (addr + strtab->sh_offset); strp = (char *) (addr + strtab->sh_offset);
for(i=0; i < nsym; i++, symp++) for (i = 0; i < nsym; i++, symp++)
{ {
/* /*
* Ignore certain types of entries which really aren't of that much * Ignore certain types of entries which really aren't of that much
...@@ -1165,7 +1272,7 @@ enum DbgInfoLoad DEBUG_LoadElfStabs(DBG_MODULE* module) ...@@ -1165,7 +1272,7 @@ enum DbgInfoLoad DEBUG_LoadElfStabs(DBG_MODULE* module)
} }
if (stabsect == -1 || stabstrsect == -1) { if (stabsect == -1 || stabstrsect == -1) {
DEBUG_Printf(DBG_CHN_WARN, "no .stab section\n"); DEBUG_Printf(DBG_CHN_WARN, "No .stab section\n");
goto leave; goto leave;
} }
...@@ -1181,7 +1288,7 @@ enum DbgInfoLoad DEBUG_LoadElfStabs(DBG_MODULE* module) ...@@ -1181,7 +1288,7 @@ enum DbgInfoLoad DEBUG_LoadElfStabs(DBG_MODULE* module)
dil = DIL_LOADED; dil = DIL_LOADED;
} else { } else {
dil = DIL_ERROR; dil = DIL_ERROR;
DEBUG_Printf(DBG_CHN_WARN, "bad stabs\n"); DEBUG_Printf(DBG_CHN_WARN, "Couldn't read correctly read stabs\n");
goto leave; goto leave;
} }
...@@ -1383,6 +1490,7 @@ static BOOL DEBUG_WalkList(struct r_debug* dbg_hdr) ...@@ -1383,6 +1490,7 @@ static BOOL DEBUG_WalkList(struct r_debug* dbg_hdr)
for (lm_addr = (u_long)dbg_hdr->r_map; lm_addr; lm_addr = (u_long)lm.l_next) { 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))) if (!DEBUG_READ_MEM_VERBOSE((void*)lm_addr, &lm, sizeof(lm)))
return FALSE; return FALSE;
if (lm.l_addr != 0 && if (lm.l_addr != 0 &&
DEBUG_READ_MEM_VERBOSE((void*)lm.l_addr, &ehdr, sizeof(ehdr)) && DEBUG_READ_MEM_VERBOSE((void*)lm.l_addr, &ehdr, sizeof(ehdr)) &&
ehdr.e_type == ET_DYN && /* only look at dynamic modules */ ehdr.e_type == ET_DYN && /* only look at dynamic modules */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment