https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105535
Bug ID: 105535 Summary: GCOV analysis on 16-bit target systems impossible Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: gcov-profile Assignee: unassigned at gcc dot gnu.org Reporter: peter-helf...@t-online.de CC: marxin at gcc dot gnu.org Target Milestone: --- Created attachment 52944 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52944&action=edit Proposed Patch file for libgcc/libgcov.h Refers to GCC versions: 9.3.1 (oldest version I tested) up to current release 12.1.0 GCOV analysis on 16-bit target systems impossible. Length divergence of struct “gcov_info” member “n_functions”. Dear GCC team, Currently I am using GCC and its libgcov for on-target code coverage analysis on a 16-bit target system (TI MSP-430). Unfortunately, during my GCOV test runs I noticed an issue which breaks code coverage analysis on 16-bit (and possibly other) systems when using libgcov to assemble and write coverage information directly on the target. The issue is caused by a length divergence between the struct member “n_functions” in the struct “gcov_info” (as declared in “libgcov.h”) and statically allocated memory in generated object files. The member “n_functions” is declared as type “unsigned” in libgcov.h. The declared size thus depends on the target system. On 32-bit systems, the “n_functions” member declaration is 32 bits wide. However, on a 16-bit system, the size of the “n_functions” element usually is reduced to 16 bits (sizeof(unsigned) == 2). This variable length, which depends on the compilation target, is not taken into account when constructing the GCOV information stored as constant data in the object file, generated at compile time. This information is generated and included for every object file instrumented for GCOV analysis. During compilation, GCC generates an instance of the “gcov_info” struct in the appropriate linker input section, where its member “n_functions” has a size of (at least) 32 bits, irrespective of the compilation target. This size is not compatible with the size declared in struct “gcov_info” on my 16-bit target, as declared in the libgcov.h C-headers. In gcc, during compilation of a source code file, the “n_functions” member is generated by invoking “get_gcov_unsigned_t()” in function “coverage_obj_init()”. The minimum size of an element generated by get_gcov_usigned_t() is there hard-coded to 32 bits. The size divergence of the “gcov_info” struct member “n_functions” causes a shift of the subsequent struct member “functions" (pointer) by 2 bytes. This in turn leads to a malfunction as soon as the pointer is accessed at runtime on the 16-bit target. The issue generally prevents the target software from collecting and outputting GCOV information on 16-bit systems and therefore seems to be a quite severe problem, especially as it usually causes unpredictable malfunction on software instrumented for GCOV analysis. I wonder why that problem has not been reported before. Possibly, code coverage analysis on 16-bit targets, using libgcov on target, is still not very common these days. Suggested solution: In GCC source file “libgcov.h”: In declaration of struct “gcov_info”: Change: “unsigned n_functions” to “gcov_unsigned_t n_functions” The gcov_unsigned_t is declared: typedef unsgined gcov_unsigned_t __attribute__ ((mode (SI))) which ensures a 32-bit size for this type. Other declarations in the context of libgcov and coverage, where the same problem would otherwise appear, have been solved in the same fashion as my proposed fix. A proposed patch is attached to this bug report. Thank you for considering my report. Best regards, Hans-Peter Helfert