]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gprofng/src/CompCom.cc
14d6fc39a60e2996f15faa13ef97c4078349ac2d
1 /* Copyright (C) 2021 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
26 #include <sys/param.h>
30 #include "StringBuilder.h"
37 CompComment::CompComment (Elf
*_elf
, int _compcom
)
41 elf_cls
= elf
->elf_getclass ();
44 CompComment::~CompComment () { }
47 CompComment::get_align (int64_t offset
, int align
)
49 int val
= (int) (offset
% align
);
56 * Preprocesses the header structure, builds a table of messages with the line
57 * numbers, PCoffsets, original index, and compmsg pointer for each message.
58 * If the show_bits field is not in the message, this routine would fill it in
59 * from the mapping from COMPMSG_ID
62 CompComment::compcom_open (CheckSrcName check_src
)
64 if (check_src
== NULL
)
66 Elf_Data
*data
= elf
->elf_getdata (compcom
);
67 uint64_t b_offset
= data
->d_off
;
68 if (get_align (b_offset
, 4)) // not align 4
70 char *CommData
= (char *) data
->d_buf
;
71 uint64_t offset
= b_offset
;
72 for (uint64_t e_offset
= b_offset
+ data
->d_size
; offset
< e_offset
;)
74 offset
+= get_align (offset
, (int) data
->d_align
);
75 if (offset
>= e_offset
)
77 compcomhdr
*hdr
= (compcomhdr
*) (CommData
+ (offset
- b_offset
));
78 int hdr_msgcount
= elf
->decode (hdr
->msgcount
);
79 int hdr_srcname
= elf
->decode (hdr
->srcname
);
80 int hdr_stringlen
= elf
->decode (hdr
->stringlen
);
81 int hdr_paramcount
= elf
->decode (hdr
->paramcount
);
82 size_t length
= sizeof (compcomhdr
) + hdr_msgcount
* sizeof (compmsg
) +
83 hdr_paramcount
* sizeof (int32_t);
84 if (offset
+ length
+ hdr_stringlen
> e_offset
|| hdr_srcname
< 0
85 || hdr_srcname
>= hdr_stringlen
)
89 char *src_name
= (char *) (((char*) hdr
) + length
+ hdr_srcname
);
90 if (check_src (src_name
))
92 msgs
= (compmsg
*) (((char *) hdr
) + sizeof (compcomhdr
));
93 params
= (int32_t *) ((char *) msgs
+ hdr_msgcount
* sizeof (compmsg
));
94 strs
= (char *) ((char *) params
+ hdr_paramcount
* sizeof (int32_t));
96 // initialize the I18N/L10N strings & set the visible table
100 offset
+= (length
+ hdr_stringlen
);
106 CompComment::get_demangle_name (char *fname
)
109 return cplus_demangle (fname
, DMGL_PARAMS
);
114 * takes the message, and returns the I18N string for the message.
117 CompComment::compcom_format (int index
, compmsg
*msg
, int &visible
)
119 compmsg
*p
= msgs
+ index
;
120 msg
->instaddr
= elf
->decode (p
->instaddr
);
121 msg
->lineno
= elf
->decode (p
->lineno
);
122 msg
->msg_type
= elf
->decode (p
->msg_type
);
123 msg
->nparam
= elf
->decode (p
->nparam
);
124 msg
->param_index
= elf
->decode (p
->param_index
);
126 int vindex
= ccm_vis_index (msg
->msg_type
);
128 Ccm_Primtype_t prim_ty
;
129 visible
= ccm_attrs
[vindex
].vis
;
130 if (ccm_attrs
[vindex
].msg
== NULL
)
132 /* Print CCM_UNKNOWN message */
133 int uindex
= ccm_vis_index (CCM_UNKNOWN
);
134 visible
= ccm_attrs
[uindex
].vis
;
135 return dbe_sprintf (ccm_attrs
[uindex
].msg
, vindex
);
139 * Construct the output buffer based on the primitive types of the
140 * message parameters.
142 * Parameter lists have to be handled carefully -- the 1 parameter
143 * is built up of all the elements separated by ", ".
145 * Old way: Case by message format string.
147 int *ind
= params
+ msg
->param_index
;
148 int plist_idx
= ccm_paramlist_index (msg
->msg_type
);
151 /* No parameter list to handle; 0 parameters case is handled */
155 MAX_COMPCOM_ARGS
= 13
157 char *parms
[MAX_COMPCOM_ARGS
];
158 if (msg
->nparam
>= MAX_COMPCOM_ARGS
)
161 GTXT ("Warning: improperly formatted compiler commentary message (%d parameters >= %d);\n please report this bug against the compiler\n"),
162 msg
->nparam
, MAX_COMPCOM_ARGS
);
165 for (int i
= 0; i
< MAX_COMPCOM_ARGS
; i
++)
166 parms
[i
] = NULL
; // initialize array
167 int prm_cnt
= ccm_num_params (msg
->msg_type
);
168 if (prm_cnt
!= msg
->nparam
)
171 GTXT ("Warning, improperly formatted compiler commentary message (parameter count mismatch = %d, param# = %d, msg_type = %x, `%s');\n please report this bug against the compiler\n"),
172 prm_cnt
, msg
->nparam
, msg
->msg_type
, ccm_attrs
[vindex
].msg
);
175 for (int i
= 0; i
< msg
->nparam
; i
++)
177 /* Parameters in message-type numbered from '1' */
178 prim_ty
= ccm_param_primtype (msg
->msg_type
, i
+ 1);
179 if (prim_ty
== CCM_PRIMTYPE_INTEGER
)
181 unsigned long v
= elf
->decode (ind
[i
]);
182 parms
[i
] = (char*) v
;
184 else if (prim_ty
== CCM_PRIMTYPE_STRING
)
186 char *fname
= strs
+ elf
->decode (ind
[i
]);
187 char *demName
= get_demangle_name (fname
);
188 parms
[i
] = demName
? demName
: dbe_strdup (fname
);
190 else if (prim_ty
== CCM_PRIMTYPE_HEXSTRING
)
191 parms
[i
] = dbe_sprintf (elf_cls
== ELFCLASS32
? NTXT ("0x%08llx") : NTXT ("0x%016llx"),
192 (unsigned long long) msg
->instaddr
);
196 GTXT ("Warning, improperly formatted compiler commentary message (unexpected primitive type %d);\n please report this bug against the compiler\n"),
198 // Dummy code to avoid compiler's warning: static function ccm_param_hightype is not used
199 Ccm_Hitype_t hightype
= CCM_HITYPE_NONE
;
200 if (hightype
!= CCM_HITYPE_NONE
)
201 hightype
= ccm_param_hightype (msg
->msg_type
, i
+ 1);
207 * Must make sure to pass _ALL_ params; may pass more because
208 * the format won't access the 'extra' parameters if all the
209 * rules for messages have been followed.
211 mbuf
= dbe_sprintf (ccm_attrs
[vindex
].msg
, parms
[0], parms
[1], parms
[2],
212 parms
[3], parms
[4], parms
[5], parms
[6], parms
[7],
213 parms
[8], parms
[9], parms
[10], parms
[11]);
214 // Cleanup allocated memory.
215 for (int i
= 0; i
< msg
->nparam
; i
++)
217 prim_ty
= ccm_param_primtype (msg
->msg_type
, i
+ 1);
218 if (prim_ty
== CCM_PRIMTYPE_STRING
|| prim_ty
== CCM_PRIMTYPE_HEXSTRING
)
225 * Parameter list messages never have 0 parameters; the
226 * primitive type for the parameter list elements is always
227 * the same. And as of 22-Sep-2006, it was always
228 * CCM_PRIMTYPE_STRING.
230 * Account for different bases of parameter indices and
231 * 'nparam' count (1 and 0, respectively).
234 if (plist_idx
> (int) ((sizeof (parms
) / sizeof (char*))))
237 GTXT ("Warning: improperly formatted compiler commentary message (msg->nparam=%d plist_idx=%d);\n please report this bug against the compiler\n"),
238 msg
->nparam
, plist_idx
);
241 for (size_t i
= 0; i
< (sizeof (parms
) / sizeof (char*)); i
++)
242 parms
[i
] = NULL
; // initialize array
245 prim_ty
= ccm_param_primtype (msg
->msg_type
, plist_idx
);
246 for (int i
= plist_idx
- 1; i
< msg
->nparam
; i
++)
248 if (i
!= plist_idx
- 1)
249 sb
.append (GTXT (", "));
250 if (prim_ty
== CCM_PRIMTYPE_INTEGER
)
251 sb
.append (elf
->decode (ind
[i
]));
252 else if (prim_ty
== CCM_PRIMTYPE_STRING
)
254 char *fname
= strs
+ elf
->decode (ind
[i
]);
255 char *demName
= get_demangle_name (fname
);
264 else if (prim_ty
== CCM_PRIMTYPE_HEXSTRING
)
265 sb
.appendf (elf_cls
== ELFCLASS32
? NTXT ("0x%08llx") : NTXT ("0x%016llx"),
266 (unsigned long long) msg
->instaddr
);
268 parms
[plist_idx
- 1] = sb
.toString ();
270 for (int i
= 0; i
< plist_idx
- 1; i
++)
272 prim_ty
= ccm_param_primtype (msg
->msg_type
, i
+ 1);
273 if (prim_ty
== CCM_PRIMTYPE_INTEGER
)
275 unsigned long v
= elf
->decode (ind
[i
]);
276 parms
[i
] = (char*) v
;
278 else if (prim_ty
== CCM_PRIMTYPE_STRING
)
280 char *fname
= strs
+ elf
->decode (ind
[i
]);
281 char *demName
= get_demangle_name (fname
);
282 parms
[i
] = demName
? demName
: dbe_strdup (fname
);
284 else if (prim_ty
== CCM_PRIMTYPE_HEXSTRING
)
285 parms
[i
] = dbe_sprintf (elf_cls
== ELFCLASS32
? NTXT ("0x%08llx") : NTXT ("0x%016llx"),
286 (unsigned long long) msg
->instaddr
);
290 GTXT ("Warning, improperly formatted compiler commentary message (unexpected primitive type %d);\n please report this bug against the compiler\n"),
297 * We have reduced the parameter list to a single string (as
298 * the printf format specifier requires), so only have
299 * 'plist_idx' parameters.
301 mbuf
= dbe_sprintf (ccm_attrs
[vindex
].msg
, parms
[0], parms
[1], parms
[2]);
303 // Cleanup allocated memory.
304 free (parms
[plist_idx
- 1]);
305 for (int i
= 0; i
< plist_idx
- 1; i
++)
307 prim_ty
= ccm_param_primtype (msg
->msg_type
, i
+ 1);
308 if (prim_ty
== CCM_PRIMTYPE_STRING
)