@@ -431,6 +431,8 @@ struct _upf_type {
431431 } as ;
432432};
433433
434+ _UPF_VECTOR_TYPEDEF (_upf_type_vec , _upf_type * );
435+
434436typedef 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
11941204static _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
12051214static 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
12181227static _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
12321239static _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
12461251static _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
12621264static _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
16291629static 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