Skip to content

Commit 0a427e4

Browse files
committed
Store DIE-less types separately
1 parent 9e236f3 commit 0a427e4

1 file changed

Lines changed: 70 additions & 71 deletions

File tree

uprintf.h

Lines changed: 70 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,8 @@ struct _upf_type {
431431
} as;
432432
};
433433

434+
_UPF_VECTOR_TYPEDEF(_upf_type_vec, _upf_type *);
435+
434436
typedef struct {
435437
uint64_t start;
436438
uint64_t end;
@@ -598,6 +600,7 @@ struct _upf_state {
598600
const uint8_t *rnglists;
599601
// parsed DWARF info
600602
_upf_type_map_vec type_map;
603+
_upf_type_vec types;
601604
_upf_cu_vec cus;
602605
_upf_extern_function_vec extern_functions;
603606
// sequential id for handling circular structs
@@ -1158,12 +1161,19 @@ static int _upf_get_type_modifier(uint64_t tag) {
11581161
_UPF_ERROR("Invalid DWARF type modifier: %lu.", tag);
11591162
}
11601163

1161-
static _upf_type *_upf_add_type(const uint8_t *type_die, _upf_type type) {
1162-
if (type_die != NULL) {
1163-
for (uint32_t i = 0; i < _upf_state.type_map.length; i++) {
1164-
_upf_type_map_entry entry = _upf_state.type_map.data[i];
1165-
if (entry.die == type_die) return entry.type_ptr;
1166-
}
1164+
static _upf_type *_upf_new_type(_upf_type type) {
1165+
_upf_type *type_ptr = _upf_alloc(sizeof(type));
1166+
memcpy(type_ptr, &type, sizeof(type));
1167+
_UPF_VECTOR_PUSH(&_upf_state.types, type_ptr);
1168+
return type_ptr;
1169+
}
1170+
1171+
static _upf_type *_upf_new_type2(const uint8_t *type_die, _upf_type type) {
1172+
_UPF_ASSERT(type_die != NULL);
1173+
1174+
for (uint32_t i = 0; i < _upf_state.type_map.length; i++) {
1175+
_upf_type_map_entry entry = _upf_state.type_map.data[i];
1176+
if (entry.die == type_die) return entry.type_ptr;
11671177
}
11681178

11691179
_upf_type *type_ptr = _upf_alloc(sizeof(type));
@@ -1192,14 +1202,13 @@ static _upf_type _upf_get_subarray(const _upf_type *array, int count) {
11921202
}
11931203

11941204
static _upf_type *_upf_get_pointer_to_type(_upf_type *type_ptr) {
1195-
_upf_type type = {
1205+
return _upf_new_type((_upf_type) {
11961206
.kind = _UPF_TK_POINTER,
11971207
.size = sizeof(void*),
11981208
.as.pointer = {
11991209
.type = type_ptr,
12001210
},
1201-
};
1202-
return _upf_add_type(NULL, type);
1211+
});
12031212
}
12041213

12051214
static bool _upf_is_pointer(const _upf_type *type) {
@@ -1212,64 +1221,55 @@ static _upf_type *_upf_dereference_type(_upf_type *type_ptr) {
12121221
_UPF_ASSERT(_upf_is_pointer(type_ptr));
12131222
if (type_ptr->kind == _UPF_TK_POINTER) return type_ptr->as.pointer.type;
12141223
if (type_ptr->as.array.lengths.length <= 1) return type_ptr->as.array.element_type;
1215-
return _upf_add_type(NULL, _upf_get_subarray(type_ptr, 1));
1224+
return _upf_new_type(_upf_get_subarray(type_ptr, 1));
12161225
}
12171226

12181227
static _upf_type *_upf_get_void_type(void) {
12191228
static _upf_type *type_ptr = NULL;
1220-
if (type_ptr != NULL) return type_ptr;
1221-
1222-
_upf_type type = {
1223-
.name = "void",
1224-
.kind = _UPF_TK_VOID,
1225-
.size = 0,
1226-
};
1227-
type_ptr = _upf_add_type(NULL, type);
1228-
1229+
if (type_ptr == NULL) {
1230+
type_ptr = _upf_new_type((_upf_type) {
1231+
.name = "void",
1232+
.kind = _UPF_TK_VOID,
1233+
.size = 0,
1234+
});
1235+
}
12291236
return type_ptr;
12301237
}
12311238

12321239
static _upf_type *_upf_get_bool_type(void) {
12331240
static _upf_type *type_ptr = NULL;
1234-
if (type_ptr != NULL) return type_ptr;
1235-
1236-
_upf_type type = {
1237-
.name = "bool",
1238-
.kind = _UPF_TK_BOOL,
1239-
.size = sizeof(bool),
1240-
};
1241-
type_ptr = _upf_add_type(NULL, type);
1242-
1241+
if (type_ptr == NULL) {
1242+
type_ptr = _upf_new_type((_upf_type) {
1243+
.name = "bool",
1244+
.kind = _UPF_TK_BOOL,
1245+
.size = sizeof(bool),
1246+
});
1247+
}
12431248
return type_ptr;
12441249
}
12451250

12461251
static _upf_type *_upf_get_cstr_type(void) {
12471252
static _upf_type *type_ptr = NULL;
1248-
if (type_ptr != NULL) return type_ptr;
1249-
1250-
_upf_type const_char_type = {
1251-
.name = "char",
1252-
.kind = _UPF_TK_SCHAR,
1253-
.size = sizeof(char),
1254-
.modifiers = _UPF_MOD_CONST,
1255-
};
1256-
_upf_type *const_char_type_ptr = _upf_add_type(NULL, const_char_type);
1257-
1258-
type_ptr = _upf_get_pointer_to_type(const_char_type_ptr);
1253+
if (type_ptr == NULL) {
1254+
type_ptr = _upf_get_pointer_to_type(_upf_new_type((_upf_type) {
1255+
.name = "char",
1256+
.kind = _UPF_TK_SCHAR,
1257+
.size = sizeof(char),
1258+
.modifiers = _UPF_MOD_CONST,
1259+
}));
1260+
}
12591261
return type_ptr;
12601262
}
12611263

12621264
static _upf_type *_upf_get_number_type(void) {
12631265
static _upf_type *type_ptr = NULL;
1264-
if (type_ptr != NULL) return type_ptr;
1265-
1266-
_upf_type type = {
1267-
.name = "int",
1268-
.kind = _UPF_TK_S4,
1269-
.size = sizeof(int),
1270-
};
1271-
type_ptr = _upf_add_type(NULL, type);
1272-
1266+
if (type_ptr == NULL) {
1267+
type_ptr = _upf_new_type((_upf_type) {
1268+
.name = "int",
1269+
.kind = _UPF_TK_S4,
1270+
.size = sizeof(int),
1271+
});
1272+
}
12731273
return type_ptr;
12741274
}
12751275

@@ -1331,7 +1331,7 @@ static _upf_type *_upf_parse_type(const _upf_cu *cu, const uint8_t *die) {
13311331
int brackets = 0;
13321332
bool is_static = true;
13331333
size_t array_size = element_type->size;
1334-
if (!abbrev->has_children) return _upf_add_type(die_base, type);
1334+
if (!abbrev->has_children) return _upf_new_type2(die_base, type);
13351335
while (true) {
13361336
die += _upf_get_abbrev(&abbrev, cu, die);
13371337
if (abbrev == NULL) break;
@@ -1391,7 +1391,7 @@ static _upf_type *_upf_parse_type(const _upf_cu *cu, const uint8_t *die) {
13911391
type.name = typename;
13921392
}
13931393

1394-
return _upf_add_type(die_base, type);
1394+
return _upf_new_type2(die_base, type);
13951395
}
13961396
case DW_TAG_enumeration_type: {
13971397
_UPF_ASSERT(subtype_offset != UINT64_MAX);
@@ -1407,7 +1407,7 @@ static _upf_type *_upf_parse_type(const _upf_cu *cu, const uint8_t *die) {
14071407

14081408
if (type.size == UINT64_MAX) type.size = type.as.cenum.underlying_type->size;
14091409

1410-
if (!abbrev->has_children) return _upf_add_type(die_base, type);
1410+
if (!abbrev->has_children) return _upf_new_type2(die_base, type);
14111411
while (true) {
14121412
die += _upf_get_abbrev(&abbrev, cu, die);
14131413
if (abbrev == NULL) break;
@@ -1437,7 +1437,7 @@ static _upf_type *_upf_parse_type(const _upf_cu *cu, const uint8_t *die) {
14371437
_UPF_VECTOR_PUSH(&type.as.cenum.enums, cenum);
14381438
}
14391439

1440-
return _upf_add_type(die_base, type);
1440+
return _upf_new_type2(die_base, type);
14411441
}
14421442
case DW_TAG_pointer_type: {
14431443
_UPF_ASSERT(size == UINT64_MAX || size == sizeof(void *));
@@ -1450,7 +1450,7 @@ static _upf_type *_upf_parse_type(const _upf_cu *cu, const uint8_t *die) {
14501450

14511451
// Pointers must be added before parsing their data to prevent
14521452
// self-referential structs from infinite recursion.
1453-
_upf_type *type_ptr = _upf_add_type(die_base, type);
1453+
_upf_type *type_ptr = _upf_new_type2(die_base, type);
14541454

14551455
if (subtype_offset == UINT64_MAX) {
14561456
type_ptr->as.pointer.type = _upf_get_void_type();
@@ -1473,7 +1473,7 @@ static _upf_type *_upf_parse_type(const _upf_cu *cu, const uint8_t *die) {
14731473
},
14741474
};
14751475

1476-
if (!abbrev->has_children) return _upf_add_type(die_base, type);
1476+
if (!abbrev->has_children) return _upf_new_type2(die_base, type);
14771477
while (true) {
14781478
die += _upf_get_abbrev(&abbrev, cu, die);
14791479
if (abbrev == NULL) break;
@@ -1523,7 +1523,7 @@ static _upf_type *_upf_parse_type(const _upf_cu *cu, const uint8_t *die) {
15231523
_UPF_VECTOR_PUSH(&type.as.cstruct.members, member);
15241524
}
15251525

1526-
return _upf_add_type(die_base, type);
1526+
return _upf_new_type2(die_base, type);
15271527
}
15281528
case DW_TAG_subroutine_type: {
15291529
_upf_type type = {
@@ -1536,7 +1536,7 @@ static _upf_type *_upf_parse_type(const _upf_cu *cu, const uint8_t *die) {
15361536
type.as.function.return_type = _upf_parse_type(cu, cu->base + subtype_offset);
15371537
}
15381538

1539-
if (!abbrev->has_children) return _upf_add_type(die_base, type);
1539+
if (!abbrev->has_children) return _upf_new_type2(die_base, type);
15401540
while (true) {
15411541
die += _upf_get_abbrev(&abbrev, cu, die);
15421542
if (abbrev == NULL) break;
@@ -1557,7 +1557,7 @@ static _upf_type *_upf_parse_type(const _upf_cu *cu, const uint8_t *die) {
15571557
}
15581558
}
15591559

1560-
return _upf_add_type(die_base, type);
1560+
return _upf_new_type2(die_base, type);
15611561
}
15621562
case DW_TAG_typedef: {
15631563
_UPF_ASSERT(name != NULL);
@@ -1568,7 +1568,7 @@ static _upf_type *_upf_parse_type(const _upf_cu *cu, const uint8_t *die) {
15681568
.kind = _UPF_TK_VOID,
15691569
.size = 0,
15701570
};
1571-
return _upf_add_type(die_base, type);
1571+
return _upf_new_type2(die_base, type);
15721572
}
15731573

15741574
_upf_type type = *_upf_parse_type(cu, cu->base + subtype_offset);
@@ -1577,7 +1577,7 @@ static _upf_type *_upf_parse_type(const _upf_cu *cu, const uint8_t *die) {
15771577
if (type.kind == _UPF_TK_SCHAR && strcmp(name, "int8_t") == 0) type.kind = _UPF_TK_S1;
15781578
else if (type.kind == _UPF_TK_UCHAR && strcmp(name, "uint8_t") == 0) type.kind = _UPF_TK_U1;
15791579

1580-
return _upf_add_type(die_base, type);
1580+
return _upf_new_type2(die_base, type);
15811581
}
15821582
case DW_TAG_base_type: {
15831583
_UPF_ASSERT(name != NULL && size != UINT64_MAX && encoding != 0);
@@ -1588,7 +1588,7 @@ static _upf_type *_upf_parse_type(const _upf_cu *cu, const uint8_t *die) {
15881588
.size = size,
15891589
};
15901590

1591-
return _upf_add_type(die_base, type);
1591+
return _upf_new_type2(die_base, type);
15921592
}
15931593
case DW_TAG_const_type:
15941594
case DW_TAG_volatile_type:
@@ -1602,12 +1602,12 @@ static _upf_type *_upf_parse_type(const _upf_cu *cu, const uint8_t *die) {
16021602
.size = sizeof(void *),
16031603
};
16041604

1605-
return _upf_add_type(die_base, type);
1605+
return _upf_new_type2(die_base, type);
16061606
} else {
16071607
_upf_type type = *_upf_parse_type(cu, cu->base + subtype_offset);
16081608
type.modifiers |= _upf_get_type_modifier(abbrev->tag);
16091609

1610-
return _upf_add_type(die_base, type);
1610+
return _upf_new_type2(die_base, type);
16111611
}
16121612
}
16131613
default:
@@ -1623,7 +1623,7 @@ static _upf_type *_upf_parse_type(const _upf_cu *cu, const uint8_t *die) {
16231623
.modifiers = 0,
16241624
.size = size,
16251625
};
1626-
return _upf_add_type(die_base, type);
1626+
return _upf_new_type2(die_base, type);
16271627
}
16281628

16291629
static bool _upf_is_in_range(uint64_t pc, _upf_range_vec ranges) {
@@ -2469,15 +2469,14 @@ static _upf_type *_upf_get_function(const _upf_cu *cu, const char *function_name
24692469

24702470
_upf_type *return_type
24712471
= function->return_type_die == NULL ? _upf_get_void_type() : _upf_parse_type(_upf_state.current_cu, function->return_type_die);
2472-
_upf_type function_type = {
2472+
return _upf_new_type((_upf_type) {
24732473
.name = function->name,
24742474
.kind = _UPF_TK_FUNCTION,
24752475
.size = sizeof(void *),
24762476
.as.function = {
24772477
.return_type = return_type,
24782478
},
2479-
};
2480-
return _upf_add_type(NULL, function_type);
2479+
});
24812480
}
24822481
return NULL;
24832482
}
@@ -2506,10 +2505,10 @@ static int _upf_parse_abstract_declarator(_upf_type **function_type, _upf_type *
25062505
_UPF_ASSERT(sub_pointers > 0);
25072506
sub_pointers--;
25082507

2509-
_upf_type *current_function_type = _upf_add_type(NULL, (_upf_type) {
2510-
.kind = _UPF_TK_FUNCTION,
2511-
.size = sizeof(void *),
2512-
});
2508+
_upf_type *current_function_type = _upf_new_type((_upf_type) {
2509+
.kind = _UPF_TK_FUNCTION,
2510+
.size = sizeof(void *),
2511+
});
25132512
_upf_type **current_function_return_type = &current_function_type->as.function.return_type;
25142513

25152514
while (sub_pointers-- > 0) current_function_type = _upf_get_pointer_to_type(current_function_type);
@@ -2655,7 +2654,7 @@ static _upf_type *_upf_parse_typename(void) {
26552654
} else {
26562655
_UPF_ERROR("Invalid integer type at %s:%d.", _upf_state.file_path, _upf_state.line);
26572656
}
2658-
type_ptr = _upf_add_type(NULL, type);
2657+
type_ptr = _upf_new_type(type);
26592658
}
26602659

26612660
_UPF_ASSERT(type_ptr != NULL);

0 commit comments

Comments
 (0)