@@ -374,7 +374,7 @@ bool dwarf_consumeSome(struct dwarf_parser* self, void* buffer, size_t* counter,
374374 case DW_FORM_strp :
375375 case DW_FORM_string :
376376 case DW_FORM_line_strp :
377- (void ) dwarf5_readString (self , buffer , counter , type );
377+ (void ) dwarf_readString (self , buffer , counter , type );
378378 break ;
379379
380380 case DW_FORM_sdata : getLEB128 (buffer , counter ); break ;
@@ -389,6 +389,116 @@ bool dwarf_consumeSome(struct dwarf_parser* self, void* buffer, size_t* counter,
389389 return true;
390390}
391391
392+ /**
393+ * Calculates a string pointer into one of the given sections.
394+ *
395+ * @param offset the string offset
396+ * @param type the type of string to load
397+ * @param debugLineStr the section corresponding to the .debug_line_str section
398+ * @param debugStr the section corresponding to the .debug_str section
399+ * @return a pointer to the string in either section or `NULL` if the given type specifies neither section
400+ */
401+ static inline char * dwarf_stringFromSection (uint64_t offset ,
402+ uint64_t type ,
403+ struct lcs_section debugLineStr ,
404+ struct lcs_section debugStr ) {
405+ char * toReturn = NULL ;
406+ switch (type ) {
407+ case DW_FORM_line_strp : toReturn = debugLineStr .content + offset ; break ;
408+ case DW_FORM_strp : toReturn = debugStr .content + offset ; break ;
409+ }
410+ return toReturn ;
411+ }
412+
413+ /**
414+ * @brief Loads the offset into the debug string section for the given index in
415+ * the given debug string offsets section.
416+ *
417+ * The section must not be empty, the index though is range checked.
418+ *
419+ * @param index the index of the offset
420+ * @param debugStrOffsets the debug string offsets section
421+ * @param offset the optional offset into the debug string offsets table
422+ * @return the optionally deducted string table offset
423+ */
424+ static inline optional_uint64_t dwarf_loadStringOffset (uint64_t index , struct lcs_section debugStrOffsets , optional_uint64_t offset ) {
425+ bool bit64 ;
426+ size_t counter = 0 ;
427+ const uint64_t size = dwarf_parseInitialSize (debugStrOffsets .content , & counter , & bit64 );
428+ if (bit64 ) {
429+ if (index >= size / 8 ) {
430+ return (optional_uint64_t ) { .has_value = false };
431+ }
432+ if (offset .has_value ) {
433+ return (optional_uint64_t ) { true, ((uint64_t * ) (debugStrOffsets .content + offset .value ))[index ] };
434+ }
435+ return (optional_uint64_t ) { true, ((uint64_t * ) (debugStrOffsets .content + counter ))[index ] };
436+ } else if (index >= size / 4 ) {
437+ return (optional_uint64_t ) { .has_value = false };
438+ }
439+ if (offset .has_value ) {
440+ return (optional_uint64_t ) { true, ((uint32_t * ) (debugStrOffsets .content + offset .value ))[index ] };
441+ }
442+ return (optional_uint64_t ) { true, ((uint32_t * ) (debugStrOffsets .content + counter ))[index ] };
443+ }
444+
445+ char * dwarf_readString (struct dwarf_parser * self , void * buffer , size_t * counter , uint64_t type ) {
446+ if (type == DW_FORM_string ) {
447+ char * toReturn = (buffer + * counter );
448+ * counter += strlen (toReturn ) + 1 ;
449+ return toReturn ;
450+ }
451+ if (type != DW_FORM_line_strp && type != DW_FORM_strp && type != DW_FORM_strp_sup
452+ && type != DW_FORM_strx && type != DW_FORM_strx1 && type != DW_FORM_strx2
453+ && type != DW_FORM_strx3 && type != DW_FORM_strx4 ) {
454+ return NULL ;
455+ }
456+ uint64_t offset ;
457+ if (type == DW_FORM_strp || type == DW_FORM_line_strp || type == DW_FORM_strp_sup ) {
458+ if (self -> bit64 ) {
459+ offset = * ((uint64_t * ) (buffer + * counter ));
460+ * counter += 8 ;
461+ } else {
462+ offset = * ((uint32_t * ) (buffer + * counter ));
463+ * counter += 4 ;
464+ }
465+ } else {
466+ uint64_t index ;
467+ switch (type ) {
468+ case DW_FORM_strx : index = getULEB128 (buffer , counter ); break ;
469+ case DW_FORM_strx1 : index = * ((uint8_t * ) (buffer + * counter ++ )); break ;
470+
471+ case DW_FORM_strx2 :
472+ index = * ((uint16_t * ) (buffer + * counter ));
473+ * counter += 2 ;
474+ break ;
475+
476+ case DW_FORM_strx3 : {
477+ uint8_t bytes [3 ];
478+ bytes [0 ] = * ((uint8_t * ) (buffer + * counter ++ ));
479+ bytes [1 ] = * ((uint8_t * ) (buffer + * counter ++ ));
480+ bytes [2 ] = * ((uint8_t * ) (buffer + * counter ++ ));
481+
482+ index = bytes [0 ] + (bytes [1 ] << 8 ) + (bytes [2 ] << 16 );
483+ break ;
484+ }
485+
486+ case DW_FORM_strx4 :
487+ index = * ((uint32_t * ) (buffer + * counter ));
488+ * counter += 4 ;
489+ break ;
490+
491+ default : return NULL ;
492+ }
493+ type = DW_FORM_strp ;
494+ optional_uint64_t value = dwarf_loadStringOffset (index , self -> debugStrOffsets , self -> debugStrOffset );
495+ if (!value .has_value ) {
496+ return NULL ;
497+ }
498+ offset = value .value ;
499+ }
500+ return dwarf_stringFromSection (offset , type , self -> debugLineStr , self -> debugStr );
501+ }
392502
393503/**
394504 * Parses the compilation directory.
@@ -441,10 +551,10 @@ static inline bool dwarf_parseCompDir(struct dwarf_parser* self) {
441551 const vector_pair_uint64_t abbrevs = dwarf_getAbbreviationTable (self -> debugAbbrev , abbrevCode , abbrevOffset , version );
442552 vector_iterate (pair_uint64_t , & abbrevs , {
443553 if (element -> first == DW_AT_comp_dir ) {
444- self -> compilationDirectory = dwarf5_readString (self ,
445- self -> debugInfo .content ,
446- & counter ,
447- element -> second );
554+ self -> compilationDirectory = dwarf_readString (self ,
555+ self -> debugInfo .content ,
556+ & counter ,
557+ element -> second );
448558 break ;
449559 } else if (version >= 5 && element -> first == DW_AT_str_offsets_base ) {
450560 if (self -> bit64 ) {
0 commit comments