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)