Skip to content

Commit

Permalink
Enumerations Support
Browse files Browse the repository at this point in the history
This commit introduces support for enumerations in C. Support
for enums took a long time because I thought there was some
way to discover the signedness of the integer type chosen by
the compiler. GCC adds the DW_AT_type field to the enum
definition in the DWARF structure. However, Clang does not
emit this field and therefore we cannot rely on its existence
to discover the signal of the type.

There would be the possibility of taking a 'mixed' approach
that checks for the existence of the field and, if any,
analyzes the base type signal. However, to keep it simple,
I will always assume enum as a signed type.
  • Loading branch information
Theldus committed Mar 7, 2020
1 parent 3eeb321 commit 1c2d53e
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 12 deletions.
9 changes: 9 additions & 0 deletions src/dwarf.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,17 @@ static int dw_parse_variable_base_type
* is the byte size.
*/
else if (tag == DW_TAG_enumeration_type)
{
*var_type = TENUM;

/*
* Lets assume signed, there is no way to
* to guess the type of the siblings
* 'DW_TAG_enumerator'. =/
*/
*encoding = ENC_SIGNED;
}

/* Base types. */
else
{
Expand Down
6 changes: 3 additions & 3 deletions src/line.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ struct array *source_lines = NULL;
*
* This buffer holds the value from before and
* after the value is changed for a single
* TBASE_TYPE and TPOINTER.
* TBASE_TYPE, TENUM and TPOINTER.
*/
static char before[BS];
static char after[BS];
Expand Down Expand Up @@ -255,7 +255,7 @@ void line_default_printer(int depth, unsigned line_no,
union var_value *v_after, int *array_idxs)
{
/* If base type. */
if (v->type.var_type & (TBASE_TYPE|TPOINTER))
if (v->type.var_type & (TBASE_TYPE|TENUM|TPOINTER))
{
fn_printf(depth, 0,
"[Line: %d] [%s] (%s) %s!, before: %s, after: %s\n",
Expand Down Expand Up @@ -329,7 +329,7 @@ void line_detailed_printer(int depth, unsigned line_no,
4;

/* If base type. */
if (v->type.var_type & (TBASE_TYPE|TPOINTER))
if (v->type.var_type & (TBASE_TYPE|TENUM|TPOINTER))
{
fn_printf(depth, 0, "[%s:%d]:%s", base_file_name, line_no, line);

Expand Down
19 changes: 10 additions & 9 deletions src/variable.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ void var_dump(struct array *vars)
/**
* @brief For a given value, buffer, encoding and size, prepares a
* formatted string with its content. It's important to note, that
* this function only formats TBASE_TYPEs.
* this function only formats TBASE_TYPE, TENUM and partially
* TPOINTERSs.
*
* @param buffer Destination buffer, that will holds the formatted
* string.
Expand Down Expand Up @@ -370,7 +371,7 @@ int var_read(union var_value *value, struct dw_variable *v, pid_t child)
* enough, otherwise, read an arbitrary amount
* of bytes.
*/
if (v->type.var_type & (TBASE_TYPE|TPOINTER))
if (v->type.var_type & (TBASE_TYPE|TENUM|TPOINTER))
{
/* Global or Static. */
if (v->scope == VGLOBAL)
Expand Down Expand Up @@ -425,7 +426,7 @@ int var_read(union var_value *value, struct dw_variable *v, pid_t child)
*
* TODO: Implement other types.
*/
if (v->type.array.var_type & (TBASE_TYPE|TPOINTER))
if (v->type.array.var_type & (TBASE_TYPE|TENUM|TPOINTER))
{
/* Global or Static. */
if (v->scope == VGLOBAL)
Expand Down Expand Up @@ -459,7 +460,7 @@ int var_read(union var_value *value, struct dw_variable *v, pid_t child)
* @param child Child process.
*
* @TODO: Implement the initialization for other types,
* other than TBASE_TYPE and TPOINTER.
* other than TBASE_TYPE, TENUM and TPOINTER.
*/
void var_initialize(struct array *vars, pid_t child)
{
Expand All @@ -473,7 +474,7 @@ void var_initialize(struct array *vars, pid_t child)
v = array_get(&vars, i, NULL);

/* Base types. */
if (v->type.var_type & (TBASE_TYPE|TPOINTER))
if (v->type.var_type & (TBASE_TYPE|TENUM|TPOINTER))
{
/*
* While initializing the variables, we do not know in advance
Expand Down Expand Up @@ -522,7 +523,7 @@ void var_initialize(struct array *vars, pid_t child)
*
* TODO: Implement other types.
*/
if (v->type.array.var_type & (TBASE_TYPE|TPOINTER))
if (v->type.array.var_type & (TBASE_TYPE|TENUM|TPOINTER))
{
/* Initialize. */
if (var_read(&v->value, v, child))
Expand All @@ -546,7 +547,7 @@ void var_initialize(struct array *vars, pid_t child)
* @param depth Function depth.
*
* @TODO: Check variable change for other types, other than
* TBASE_TYPE and TPOINTER.
* TBASE_TYPE, TENUM and TPOINTER.
*/
void var_check_changes(struct breakpoint *b, struct array *vars, pid_t child, int depth)
{
Expand All @@ -560,7 +561,7 @@ void var_check_changes(struct breakpoint *b, struct array *vars, pid_t child, in
v = array_get(&vars, i, NULL);

/* If base type. */
if (v->type.var_type & (TBASE_TYPE|TPOINTER))
if (v->type.var_type & (TBASE_TYPE|TENUM|TPOINTER))
{
/* Read and compares its value. */
var_read(&value, v, child);
Expand Down Expand Up @@ -611,7 +612,7 @@ void var_check_changes(struct breakpoint *b, struct array *vars, pid_t child, in
*
* TODO: Implement other types.
*/
if (v->type.array.var_type & (TBASE_TYPE|TPOINTER))
if (v->type.array.var_type & (TBASE_TYPE|TENUM|TPOINTER))
{
int changed; /* Variable status. */
char *v1, *cmp1; /* Variable old. */
Expand Down

0 comments on commit 1c2d53e

Please sign in to comment.