diff options
58 files changed, 1560 insertions, 855 deletions
diff --git a/bfd/version.h b/bfd/version.h index d8c882e..a28cdf3 100644 --- a/bfd/version.h +++ b/bfd/version.h @@ -16,7 +16,7 @@ In releases, the date is not included in either version strings or sonames. */ -#define BFD_VERSION_DATE 20250504 +#define BFD_VERSION_DATE 20250506 #define BFD_VERSION @bfd_version@ #define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@ #define REPORT_BUGS_TO @report_bugs_to@ diff --git a/binutils/resbin.c b/binutils/resbin.c index 98dd68b..01046ec 100644 --- a/binutils/resbin.c +++ b/binutils/resbin.c @@ -136,7 +136,7 @@ get_unicode (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length, toosmall (_("null terminated unicode string")); return NULL; } - if (windres_get_16 (wrbfd, data + c * 2, 2) == 0) + if (windres_get_16 (wrbfd, data + c * 2) == 0) break; ++c; } @@ -144,7 +144,7 @@ get_unicode (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length, ret = res_alloc ((c + 1) * sizeof (unichar)); for (i = 0; i < c; i++) - ret[i] = windres_get_16 (wrbfd, data + i * 2, 2); + ret[i] = windres_get_16 (wrbfd, data + i * 2); ret[i] = 0; if (retlen != NULL) @@ -167,7 +167,7 @@ get_resid (windres_bfd *wrbfd, rc_res_id *id, const bfd_byte *data, return -1; } - first = windres_get_16 (wrbfd, data, 2); + first = windres_get_16 (wrbfd, data); if (first == 0xffff) { if (length < 4) @@ -176,7 +176,7 @@ get_resid (windres_bfd *wrbfd, rc_res_id *id, const bfd_byte *data, return -1; } id->named = 0; - id->u.id = windres_get_16 (wrbfd, data + 2, 2); + id->u.id = windres_get_16 (wrbfd, data + 2); return 4; } else @@ -221,8 +221,8 @@ bin_to_res_cursor (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length } c = res_alloc (sizeof (rc_cursor)); - c->xhotspot = windres_get_16 (wrbfd, data, 2); - c->yhotspot = windres_get_16 (wrbfd, data + 2, 2); + c->xhotspot = windres_get_16 (wrbfd, data); + c->yhotspot = windres_get_16 (wrbfd, data + 2); c->length = length - 4; c->data = data + 4; @@ -254,7 +254,7 @@ bin_to_res_menu (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length) return NULL; } - version = windres_get_16 (wrbfd, data, 2); + version = windres_get_16 (wrbfd, data); if (version == 0) { @@ -277,8 +277,8 @@ bin_to_res_menu (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length) toosmall (_("menuex header")); return NULL; } - m->help = windres_get_32 (wrbfd, data + 4, 4); - offset = windres_get_16 (wrbfd, data + 2, 2); + m->help = windres_get_32 (wrbfd, data + 4); + offset = windres_get_16 (wrbfd, data + 2); if (offset + 4 >= length) { toosmall (_("menuex offset")); @@ -327,7 +327,7 @@ bin_to_res_menuitems (windres_bfd *wrbfd, const bfd_byte *data, mi->state = 0; mi->help = 0; - flags = windres_get_16 (wrbfd, data, 2); + flags = windres_get_16 (wrbfd, data); mi->type = flags &~ (MENUITEM_POPUP | MENUITEM_ENDMENU); if ((flags & MENUITEM_POPUP) == 0) @@ -341,7 +341,7 @@ bin_to_res_menuitems (windres_bfd *wrbfd, const bfd_byte *data, return NULL; } - if (windres_get_16 (wrbfd, data + stroff, 2) == 0) + if (windres_get_16 (wrbfd, data + stroff) == 0) { slen = 0; mi->text = NULL; @@ -358,7 +358,7 @@ bin_to_res_menuitems (windres_bfd *wrbfd, const bfd_byte *data, if ((flags & MENUITEM_POPUP) == 0) { mi->popup = NULL; - mi->id = windres_get_16 (wrbfd, data + 2, 2); + mi->id = windres_get_16 (wrbfd, data + 2); } else { @@ -413,13 +413,13 @@ bin_to_res_menuexitems (windres_bfd *wrbfd, const bfd_byte *data, } mi = res_alloc (sizeof (rc_menuitem)); - mi->type = windres_get_32 (wrbfd, data, 4); - mi->state = windres_get_32 (wrbfd, data + 4, 4); - mi->id = windres_get_32 (wrbfd, data + 8, 4); + mi->type = windres_get_32 (wrbfd, data); + mi->state = windres_get_32 (wrbfd, data + 4); + mi->id = windres_get_32 (wrbfd, data + 8); - flags = windres_get_16 (wrbfd, data + 12, 2); + flags = windres_get_16 (wrbfd, data + 12); - if (windres_get_16 (wrbfd, data + 14, 2) == 0) + if (windres_get_16 (wrbfd, data + 14) == 0) { slen = 0; mi->text = NULL; @@ -448,7 +448,7 @@ bin_to_res_menuexitems (windres_bfd *wrbfd, const bfd_byte *data, toosmall (_("menuitem")); return NULL; } - mi->help = windres_get_32 (wrbfd, data + itemlen, 4); + mi->help = windres_get_32 (wrbfd, data + itemlen); itemlen += 4; mi->popup = bin_to_res_menuexitems (wrbfd, data + itemlen, @@ -494,19 +494,19 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length d = res_alloc (sizeof (rc_dialog)); - signature = windres_get_16 (wrbfd, data + 2, 2); + signature = windres_get_16 (wrbfd, data + 2); if (signature != 0xffff) { d->ex = NULL; - d->style = windres_get_32 (wrbfd, data, 4); - d->exstyle = windres_get_32 (wrbfd, data + 4, 4); + d->style = windres_get_32 (wrbfd, data); + d->exstyle = windres_get_32 (wrbfd, data + 4); off = 8; } else { int version; - version = windres_get_16 (wrbfd, data, 2); + version = windres_get_16 (wrbfd, data); if (version != 1) { non_fatal (_("unexpected DIALOGEX version %d"), version); @@ -514,9 +514,9 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length } d->ex = res_alloc (sizeof (rc_dialog_ex)); - d->ex->help = windres_get_32 (wrbfd, data + 4, 4); - d->exstyle = windres_get_32 (wrbfd, data + 8, 4); - d->style = windres_get_32 (wrbfd, data + 12, 4); + d->ex->help = windres_get_32 (wrbfd, data + 4); + d->exstyle = windres_get_32 (wrbfd, data + 8); + d->style = windres_get_32 (wrbfd, data + 12); off = 16; } @@ -526,11 +526,11 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length return NULL; } - c = windres_get_16 (wrbfd, data + off, 2); - d->x = windres_get_16 (wrbfd, data + off + 2, 2); - d->y = windres_get_16 (wrbfd, data + off + 4, 2); - d->width = windres_get_16 (wrbfd, data + off + 6, 2); - d->height = windres_get_16 (wrbfd, data + off + 8, 2); + c = windres_get_16 (wrbfd, data + off); + d->x = windres_get_16 (wrbfd, data + off + 2); + d->y = windres_get_16 (wrbfd, data + off + 4); + d->width = windres_get_16 (wrbfd, data + off + 6); + d->height = windres_get_16 (wrbfd, data + off + 8); off += 10; @@ -570,7 +570,7 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length return NULL; } - d->pointsize = windres_get_16 (wrbfd, data + off, 2); + d->pointsize = windres_get_16 (wrbfd, data + off); off += 2; if (d->ex != NULL) @@ -580,9 +580,9 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length toosmall (_("dialogex font information")); return NULL; } - d->ex->weight = windres_get_16 (wrbfd, data + off, 2); - d->ex->italic = windres_get_8 (wrbfd, data + off + 2, 1); - d->ex->charset = windres_get_8 (wrbfd, data + off + 3, 1); + d->ex->weight = windres_get_16 (wrbfd, data + off); + d->ex->italic = windres_get_8 (wrbfd, data + off + 2); + d->ex->charset = windres_get_8 (wrbfd, data + off + 3); off += 4; } @@ -612,8 +612,8 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length return NULL; } - dc->style = windres_get_32 (wrbfd, data + off, 4); - dc->exstyle = windres_get_32 (wrbfd, data + off + 4, 4); + dc->style = windres_get_32 (wrbfd, data + off); + dc->exstyle = windres_get_32 (wrbfd, data + off + 4); dc->help = 0; off += 8; } @@ -624,9 +624,9 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length toosmall (_("dialogex control")); return NULL; } - dc->help = windres_get_32 (wrbfd, data + off, 4); - dc->exstyle = windres_get_32 (wrbfd, data + off + 4, 4); - dc->style = windres_get_32 (wrbfd, data + off + 8, 4); + dc->help = windres_get_32 (wrbfd, data + off); + dc->exstyle = windres_get_32 (wrbfd, data + off + 4); + dc->style = windres_get_32 (wrbfd, data + off + 8); off += 12; } @@ -636,15 +636,15 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length return NULL; } - dc->x = windres_get_16 (wrbfd, data + off, 2); - dc->y = windres_get_16 (wrbfd, data + off + 2, 2); - dc->width = windres_get_16 (wrbfd, data + off + 4, 2); - dc->height = windres_get_16 (wrbfd, data + off + 6, 2); + dc->x = windres_get_16 (wrbfd, data + off); + dc->y = windres_get_16 (wrbfd, data + off + 2); + dc->width = windres_get_16 (wrbfd, data + off + 4); + dc->height = windres_get_16 (wrbfd, data + off + 6); if (d->ex != NULL) - dc->id = windres_get_32 (wrbfd, data + off + 8, 4); + dc->id = windres_get_32 (wrbfd, data + off + 8); else - dc->id = windres_get_16 (wrbfd, data + off + 8, 2); + dc->id = windres_get_16 (wrbfd, data + off + 8); off += 10 + (d->ex != NULL ? 2 : 0); @@ -664,7 +664,7 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length return NULL; } - datalen = windres_get_16 (wrbfd, data + off, 2); + datalen = windres_get_16 (wrbfd, data + off); off += 2; if (datalen == 0) @@ -718,7 +718,7 @@ bin_to_res_string (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length toosmall (_("stringtable string length")); return NULL; } - slen = windres_get_16 (wrbfd, data, 2); + slen = windres_get_16 (wrbfd, data); st->strings[i].length = slen; if (slen > 0) @@ -736,7 +736,7 @@ bin_to_res_string (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length st->strings[i].string = s; for (j = 0; j < slen; j++) - s[j] = windres_get_16 (wrbfd, data + 2 + j * 2, 2); + s[j] = windres_get_16 (wrbfd, data + 2 + j * 2); } data += 2 + 2 * slen; @@ -766,7 +766,7 @@ bin_to_res_fontdir (windres_bfd *wrbfd, const bfd_byte *data, return NULL; } - c = windres_get_16 (wrbfd, data, 2); + c = windres_get_16 (wrbfd, data); first = NULL; pp = &first; @@ -785,7 +785,7 @@ bin_to_res_fontdir (windres_bfd *wrbfd, const bfd_byte *data, bfi = (const struct bin_fontdir_item *) data; fd = res_alloc (sizeof *fd); - fd->index = windres_get_16 (wrbfd, bfi->index, 2); + fd->index = windres_get_16 (wrbfd, bfi->index); /* To work out the length of the fontdir data, we must get the length of the device name and face name strings, even though @@ -858,9 +858,9 @@ bin_to_res_accelerators (windres_bfd *wrbfd, const bfd_byte *data, a = res_alloc (sizeof (rc_accelerator)); - a->flags = windres_get_16 (wrbfd, data, 2); - a->key = windres_get_16 (wrbfd, data + 2, 2); - a->id = windres_get_16 (wrbfd, data + 4, 2); + a->flags = windres_get_16 (wrbfd, data); + a->key = windres_get_16 (wrbfd, data + 2); + a->id = windres_get_16 (wrbfd, data + 4); a->next = NULL; *pp = a; @@ -919,14 +919,14 @@ bin_to_res_group_cursor (windres_bfd *wrbfd, const bfd_byte *data, return NULL; } - type = windres_get_16 (wrbfd, data + 2, 2); + type = windres_get_16 (wrbfd, data + 2); if (type != 2) { non_fatal (_("unexpected group cursor type %d"), type); return NULL; } - c = windres_get_16 (wrbfd, data + 4, 2); + c = windres_get_16 (wrbfd, data + 4); data += 6; length -= 6; @@ -946,12 +946,12 @@ bin_to_res_group_cursor (windres_bfd *wrbfd, const bfd_byte *data, gc = res_alloc (sizeof *gc); - gc->width = windres_get_16 (wrbfd, data, 2); - gc->height = windres_get_16 (wrbfd, data + 2, 2); - gc->planes = windres_get_16 (wrbfd, data + 4, 2); - gc->bits = windres_get_16 (wrbfd, data + 6, 2); - gc->bytes = windres_get_32 (wrbfd, data + 8, 4); - gc->index = windres_get_16 (wrbfd, data + 12, 2); + gc->width = windres_get_16 (wrbfd, data); + gc->height = windres_get_16 (wrbfd, data + 2); + gc->planes = windres_get_16 (wrbfd, data + 4); + gc->bits = windres_get_16 (wrbfd, data + 6); + gc->bytes = windres_get_32 (wrbfd, data + 8); + gc->index = windres_get_16 (wrbfd, data + 12); gc->next = NULL; *pp = gc; @@ -984,14 +984,14 @@ bin_to_res_group_icon (windres_bfd *wrbfd, const bfd_byte *data, return NULL; } - type = windres_get_16 (wrbfd, data + 2, 2); + type = windres_get_16 (wrbfd, data + 2); if (type != 1) { non_fatal (_("unexpected group icon type %d"), type); return NULL; } - c = windres_get_16 (wrbfd, data + 4, 2); + c = windres_get_16 (wrbfd, data + 4); data += 6; length -= 6; @@ -1011,13 +1011,13 @@ bin_to_res_group_icon (windres_bfd *wrbfd, const bfd_byte *data, gi = res_alloc (sizeof (rc_group_icon)); - gi->width = windres_get_8 (wrbfd, data, 1); - gi->height = windres_get_8 (wrbfd, data + 1, 1); - gi->colors = windres_get_8 (wrbfd, data + 2, 1); - gi->planes = windres_get_16 (wrbfd, data + 4, 2); - gi->bits = windres_get_16 (wrbfd, data + 6, 2); - gi->bytes = windres_get_32 (wrbfd, data + 8, 4); - gi->index = windres_get_16 (wrbfd, data + 12, 2); + gi->width = windres_get_8 (wrbfd, data); + gi->height = windres_get_8 (wrbfd, data + 1); + gi->colors = windres_get_8 (wrbfd, data + 2); + gi->planes = windres_get_16 (wrbfd, data + 4); + gi->bits = windres_get_16 (wrbfd, data + 6); + gi->bytes = windres_get_32 (wrbfd, data + 8); + gi->index = windres_get_16 (wrbfd, data + 12); gi->next = NULL; *pp = gi; @@ -1051,9 +1051,9 @@ get_version_header (windres_bfd *wrbfd, const bfd_byte *data, return false; } - *len = (windres_get_16 (wrbfd, data, 2) + 3) & ~3; - *vallen = windres_get_16 (wrbfd, data + 2, 2); - *type = windres_get_16 (wrbfd, data + 4, 2); + *len = (windres_get_16 (wrbfd, data) + 3) & ~3; + *vallen = windres_get_16 (wrbfd, data + 2); + *type = windres_get_16 (wrbfd, data + 4); *off = 6; @@ -1078,7 +1078,7 @@ get_version_header (windres_bfd *wrbfd, const bfd_byte *data, toosmall (key); return false; } - if (windres_get_16 (wrbfd, data, 2) != (bfd_byte) *key) + if (windres_get_16 (wrbfd, data) != (bfd_byte) *key) { non_fatal (_("unexpected version string")); return false; @@ -1155,14 +1155,14 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, return NULL; } - signature = windres_get_32 (wrbfd, data, 4); + signature = windres_get_32 (wrbfd, data); if (signature != 0xfeef04bd) { non_fatal (_("unexpected fixed version signature %lu"), signature); return NULL; } - fiv = windres_get_32 (wrbfd, data + 4, 4); + fiv = windres_get_32 (wrbfd, data + 4); if (fiv != 0 && fiv != 0x10000) { non_fatal (_("unexpected fixed version info version %lu"), fiv); @@ -1171,17 +1171,17 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, fi = res_alloc (sizeof (rc_fixed_versioninfo)); - fi->file_version_ms = windres_get_32 (wrbfd, data + 8, 4); - fi->file_version_ls = windres_get_32 (wrbfd, data + 12, 4); - fi->product_version_ms = windres_get_32 (wrbfd, data + 16, 4); - fi->product_version_ls = windres_get_32 (wrbfd, data + 20, 4); - fi->file_flags_mask = windres_get_32 (wrbfd, data + 24, 4); - fi->file_flags = windres_get_32 (wrbfd, data + 28, 4); - fi->file_os = windres_get_32 (wrbfd, data + 32, 4); - fi->file_type = windres_get_32 (wrbfd, data + 36, 4); - fi->file_subtype = windres_get_32 (wrbfd, data + 40, 4); - fi->file_date_ms = windres_get_32 (wrbfd, data + 44, 4); - fi->file_date_ls = windres_get_32 (wrbfd, data + 48, 4); + fi->file_version_ms = windres_get_32 (wrbfd, data + 8); + fi->file_version_ls = windres_get_32 (wrbfd, data + 12); + fi->product_version_ms = windres_get_32 (wrbfd, data + 16); + fi->product_version_ls = windres_get_32 (wrbfd, data + 20); + fi->file_flags_mask = windres_get_32 (wrbfd, data + 24); + fi->file_flags = windres_get_32 (wrbfd, data + 28); + fi->file_os = windres_get_32 (wrbfd, data + 32); + fi->file_type = windres_get_32 (wrbfd, data + 36); + fi->file_subtype = windres_get_32 (wrbfd, data + 40); + fi->file_date_ms = windres_get_32 (wrbfd, data + 44); + fi->file_date_ls = windres_get_32 (wrbfd, data + 48); data += 52; length -= 52; @@ -1203,7 +1203,7 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, vi = res_alloc (sizeof (rc_ver_info)); - ch = windres_get_16 (wrbfd, data + 6, 2); + ch = windres_get_16 (wrbfd, data + 6); if (ch == 'S') { @@ -1366,8 +1366,8 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, vv = res_alloc (sizeof (rc_ver_varinfo)); - vv->language = windres_get_16 (wrbfd, data, 2); - vv->charset = windres_get_16 (wrbfd, data + 2, 2); + vv->language = windres_get_16 (wrbfd, data); + vv->charset = windres_get_16 (wrbfd, data + 2); vv->next = NULL; *ppvv = vv; @@ -1453,9 +1453,9 @@ bin_to_res_toolbar (windres_bfd *wrbfd, const bfd_byte *data, return NULL; } ri = res_alloc (sizeof (rc_toolbar)); - ri->button_width = windres_get_32 (wrbfd, data, 4); - ri->button_height = windres_get_32 (wrbfd, data + 4, 4); - ri->nitems = windres_get_32 (wrbfd, data + 8, 4); + ri->button_width = windres_get_32 (wrbfd, data); + ri->button_height = windres_get_32 (wrbfd, data + 4); + ri->nitems = windres_get_32 (wrbfd, data + 8); ri->items = NULL; data += 12; @@ -1470,7 +1470,7 @@ bin_to_res_toolbar (windres_bfd *wrbfd, const bfd_byte *data, toosmall (_("toolbar item")); return NULL; } - it->id.u.id = (int) windres_get_32 (wrbfd, data, 4); + it->id.u.id = (int) windres_get_32 (wrbfd, data); it->prev = it->next = NULL; data += 4; length -= 4; diff --git a/binutils/rescoff.c b/binutils/rescoff.c index 6031602..14546a4 100644 --- a/binutils/rescoff.c +++ b/binutils/rescoff.c @@ -232,14 +232,14 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data, erd = (const struct extern_res_directory *) data; rd = (rc_res_directory *) res_alloc (sizeof (rc_res_directory)); - rd->characteristics = windres_get_32 (wrbfd, erd->characteristics, 4); - rd->time = windres_get_32 (wrbfd, erd->time, 4); - rd->major = windres_get_16 (wrbfd, erd->major, 2); - rd->minor = windres_get_16 (wrbfd, erd->minor, 2); + rd->characteristics = windres_get_32 (wrbfd, erd->characteristics); + rd->time = windres_get_32 (wrbfd, erd->time); + rd->major = windres_get_16 (wrbfd, erd->major); + rd->minor = windres_get_16 (wrbfd, erd->minor); rd->entries = NULL; - name_count = windres_get_16 (wrbfd, erd->name_count, 2); - id_count = windres_get_16 (wrbfd, erd->id_count, 2); + name_count = windres_get_16 (wrbfd, erd->name_count); + id_count = windres_get_16 (wrbfd, erd->id_count); pp = &rd->entries; @@ -261,8 +261,8 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data, return NULL; } - name = windres_get_32 (wrbfd, ere->name, 4); - rva = windres_get_32 (wrbfd, ere->rva, 4); + name = windres_get_32 (wrbfd, ere->name); + rva = windres_get_32 (wrbfd, ere->rva); /* For some reason the high bit in NAME is set. */ name &=~ 0x80000000; @@ -279,7 +279,7 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data, overrun (flaginfo, _("resource name")); return NULL; } - length = windres_get_16 (wrbfd, ers, 2); + length = windres_get_16 (wrbfd, ers); /* PR 17512: file: 05dc4a16. */ if (length * 2 + 4 > flaginfo->data_end - ers) { @@ -292,7 +292,7 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data, re->id.u.n.length = length; re->id.u.n.name = (unichar *) res_alloc (length * sizeof (unichar)); for (j = 0; j < length; j++) - re->id.u.n.name[j] = windres_get_16 (wrbfd, ers + j * 2 + 2, 2); + re->id.u.n.name[j] = windres_get_16 (wrbfd, ers + j * 2 + 2); if (level == 0) type = &re->id; @@ -337,8 +337,8 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data, return NULL; } - name = windres_get_32 (wrbfd, ere->name, 4); - rva = windres_get_32 (wrbfd, ere->rva, 4); + name = windres_get_32 (wrbfd, ere->name); + rva = windres_get_32 (wrbfd, ere->rva); re = (rc_res_entry *) res_alloc (sizeof *re); re->next = NULL; @@ -405,8 +405,8 @@ read_coff_data_entry (windres_bfd *wrbfd, const bfd_byte *data, erd = (const struct extern_res_data *) data; - size = windres_get_32 (wrbfd, erd->size, 4); - rva = windres_get_32 (wrbfd, erd->rva, 4); + size = windres_get_32 (wrbfd, erd->size); + rva = windres_get_32 (wrbfd, erd->rva); if (rva < flaginfo->secaddr || rva - flaginfo->secaddr >= (rc_uint_type) (flaginfo->data_end - flaginfo->data)) { @@ -426,8 +426,8 @@ read_coff_data_entry (windres_bfd *wrbfd, const bfd_byte *data, if (r != NULL) { memset (&r->res_info, 0, sizeof (rc_res_res_info)); - r->coff_info.codepage = windres_get_32 (wrbfd, erd->codepage, 4); - r->coff_info.reserved = windres_get_32 (wrbfd, erd->reserved, 4); + r->coff_info.codepage = windres_get_32 (wrbfd, erd->codepage); + r->coff_info.reserved = windres_get_32 (wrbfd, erd->reserved); } return r; diff --git a/binutils/resrc.c b/binutils/resrc.c index 8f9451b..4ab830f 100644 --- a/binutils/resrc.c +++ b/binutils/resrc.c @@ -299,7 +299,7 @@ run_cmd (char *cmd, const char *redir) if (WEXITSTATUS (wait_status) != 0) { fatal (_("%s exited with status %d"), cmd, - WEXITSTATUS (wait_status)); + WEXITSTATUS (wait_status)); retcode = 1; } } @@ -331,7 +331,7 @@ open_input_stream (char *cmd) if (verbose) fprintf (stderr, - _("Using temporary file `%s' to read preprocessor output\n"), + _("Using temporary file `%s' to read preprocessor output\n"), cpp_temp_file); } else @@ -359,15 +359,15 @@ filename_need_quotes (const char *filename) while (*filename != 0) { switch (*filename) - { - case '&': - case ' ': - case '<': - case '>': - case '|': - case '%': - return 1; - } + { + case '&': + case ' ': + case '<': + case '>': + case '|': + case '%': + return 1; + } ++filename; } return 0; @@ -529,7 +529,7 @@ read_rc_file (const char *filename, const char *preprocessor, if (slash && ! cpp_pipe) { /* Next, try looking for a gcc in the same directory as - that windres */ + that windres */ cpp_pipe = look_for_default (cmd, program_name, slash - program_name + 1, preprocargs, filename); @@ -586,11 +586,11 @@ close_input_stream (void) else { if (cpp_pipe != NULL) - { + { int err; err = pclose (cpp_pipe); /* We are reading from a pipe, therefore we don't - know if cpp failed or succeeded until pclose. */ + know if cpp failed or succeeded until pclose. */ if (err != 0 || errno == ECHILD) { /* Since this is also run via xatexit, safeguard. */ @@ -598,7 +598,7 @@ close_input_stream (void) cpp_temp_file = NULL; fatal (_("preprocessing failed.")); } - } + } } /* Since this is also run via xatexit, safeguard. */ @@ -679,6 +679,22 @@ get_data (FILE *e, bfd_byte *p, rc_uint_type c, const char *msg) fatal (_("%s: read of %lu returned %lu"), msg, (unsigned long) c, (unsigned long) got); } + +static rc_uint_type +target_get_16 (const void *p, size_t len) +{ + if (len < 2) + fatal (_("not enough data")); + return windres_get_16 (&wrtarget, p); +} + +static rc_uint_type +target_get_32 (const void *p, size_t len) +{ + if (len < 4) + fatal (_("not enough data")); + return windres_get_32 (&wrtarget, p); +} /* Define an accelerator resource. */ @@ -1094,7 +1110,7 @@ define_fontdir_rcdata (rc_res_id id,const rc_res_res_info *resinfo, if (pb_data) { rc_uint_type off = 2; - c = windres_get_16 (&wrtarget, pb_data, len_data); + c = target_get_16 (pb_data, len_data); for (; c > 0; c--) { size_t len; @@ -1103,7 +1119,7 @@ define_fontdir_rcdata (rc_res_id id,const rc_res_res_info *resinfo, bfi = (const struct bin_fontdir_item *) pb_data + off; fd = (rc_fontdir *) res_alloc (sizeof (rc_fontdir)); - fd->index = windres_get_16 (&wrtarget, bfi->index, len_data - off); + fd->index = target_get_16 (bfi->index, len_data - off); fd->data = pb_data + off; off += 56; len = strlen ((char *) bfi->device_name) + 1; @@ -1230,8 +1246,8 @@ define_icon (rc_res_id id, const rc_res_res_info *resinfo, rc_group_icon *cg; /* For some reason, at least in some files the planes and bits - are zero. We instead set them from the color. This is - copied from rcl. */ + are zero. We instead set them from the color. This is + copied from rcl. */ cg = (rc_group_icon *) res_alloc (sizeof (rc_group_icon)); cg->next = NULL; @@ -1288,10 +1304,10 @@ define_group_icon_rcdata (rc_res_id id, const rc_res_res_info *resinfo, { int c, i; unsigned short type; - type = windres_get_16 (&wrtarget, pb_data + 2, len_data - 2); + type = target_get_16 (pb_data + 2, len_data - 2); if (type != 1) fatal (_("unexpected group icon type %d"), type); - c = windres_get_16 (&wrtarget, pb_data + 4, len_data - 4); + c = target_get_16 (pb_data + 4, len_data - 4); len_data -= 6; pb_data += 6; @@ -1304,10 +1320,10 @@ define_group_icon_rcdata (rc_res_id id, const rc_res_res_info *resinfo, cg->width = pb_data[0]; cg->height = pb_data[1]; cg->colors = pb_data[2]; - cg->planes = windres_get_16 (&wrtarget, pb_data + 4, len_data - 4); - cg->bits = windres_get_16 (&wrtarget, pb_data + 6, len_data - 6); - cg->bytes = windres_get_32 (&wrtarget, pb_data + 8, len_data - 8); - cg->index = windres_get_16 (&wrtarget, pb_data + 12, len_data - 12); + cg->planes = target_get_16 (pb_data + 4, len_data - 4); + cg->bits = target_get_16 (pb_data + 6, len_data - 6); + cg->bytes = target_get_32 (pb_data + 8, len_data - 8); + cg->index = target_get_16 (pb_data + 12, len_data - 12); if (! first) first = cg; else @@ -1341,10 +1357,10 @@ define_group_cursor_rcdata (rc_res_id id, const rc_res_res_info *resinfo, { int c, i; unsigned short type; - type = windres_get_16 (&wrtarget, pb_data + 2, len_data - 2); + type = target_get_16 (pb_data + 2, len_data - 2); if (type != 2) fatal (_("unexpected group cursor type %d"), type); - c = windres_get_16 (&wrtarget, pb_data + 4, len_data - 4); + c = target_get_16 (pb_data + 4, len_data - 4); len_data -= 6; pb_data += 6; @@ -1354,12 +1370,12 @@ define_group_cursor_rcdata (rc_res_id id, const rc_res_res_info *resinfo, fatal ("too small group icon rcdata"); cg = (rc_group_cursor *) res_alloc (sizeof (rc_group_cursor)); cg->next = NULL; - cg->width = windres_get_16 (&wrtarget, pb_data, len_data); - cg->height = windres_get_16 (&wrtarget, pb_data + 2, len_data - 2); - cg->planes = windres_get_16 (&wrtarget, pb_data + 4, len_data - 4); - cg->bits = windres_get_16 (&wrtarget, pb_data + 6, len_data - 6); - cg->bytes = windres_get_32 (&wrtarget, pb_data + 8, len_data - 8); - cg->index = windres_get_16 (&wrtarget, pb_data + 12, len_data - 12); + cg->width = target_get_16 (pb_data, len_data); + cg->height = target_get_16 (pb_data + 2, len_data - 2); + cg->planes = target_get_16 (pb_data + 4, len_data - 4); + cg->bits = target_get_16 (pb_data + 6, len_data - 6); + cg->bytes = target_get_32 (pb_data + 8, len_data - 8); + cg->index = target_get_16 (pb_data + 12, len_data - 12); if (! first) first = cg; else @@ -1389,8 +1405,8 @@ define_cursor_rcdata (rc_res_id id, const rc_res_res_info *resinfo, pb_data = rcdata_render_as_buffer (data, &len_data); c = (rc_cursor *) res_alloc (sizeof (rc_cursor)); - c->xhotspot = windres_get_16 (&wrtarget, pb_data, len_data); - c->yhotspot = windres_get_16 (&wrtarget, pb_data + 2, len_data - 2); + c->xhotspot = target_get_16 (pb_data, len_data); + c->yhotspot = target_get_16 (pb_data + 2, len_data - 2); c->length = len_data - BIN_CURSOR_SIZE; c->data = (const bfd_byte *) (data + BIN_CURSOR_SIZE); @@ -1994,9 +2010,9 @@ write_rc_directory (FILE *e, const rc_res_directory *rd, { case 1: /* If we're at level 1, the key of this resource is the - type. This normally duplicates the information we have - stored with the resource itself, but we need to remember - the type if this is a user define resource type. */ + type. This normally duplicates the information we have + stored with the resource itself, but we need to remember + the type if this is a user define resource type. */ type = &re->id; break; @@ -2031,10 +2047,10 @@ write_rc_directory (FILE *e, const rc_res_directory *rd, if (level == 3) { /* This is the normal case: the three levels are - TYPE/NAME/LANGUAGE. NAME will have been set at level - 2, and represents the name to use. We probably just - set LANGUAGE, and it will probably match what the - resource itself records if anything. */ + TYPE/NAME/LANGUAGE. NAME will have been set at level + 2, and represents the name to use. We probably just + set LANGUAGE, and it will probably match what the + resource itself records if anything. */ write_rc_resource (e, type, name, re->u.res, language); } else @@ -2493,7 +2509,7 @@ write_rc_cursor (FILE *e, const rc_cursor *cursor) (unsigned int) cursor->xhotspot, (unsigned int) cursor->yhotspot, (int) cursor->xhotspot, (int) cursor->yhotspot); write_rc_datablock (e, (rc_uint_type) cursor->length, (const bfd_byte *) cursor->data, - 0, 0, 0); + 0, 0, 0); fprintf (e, "END\n"); } @@ -2654,10 +2670,10 @@ write_rc_dialog_control (FILE *e, const rc_dialog_control *control) /* For EDITTEXT, COMBOBOX, LISTBOX, and SCROLLBAR don't dump text. */ if ((control->text.named || control->text.u.id != 0) && (!ci - || (ci->class != CTL_EDIT - && ci->class != CTL_COMBOBOX - && ci->class != CTL_LISTBOX - && ci->class != CTL_SCROLLBAR))) + || (ci->class != CTL_EDIT + && ci->class != CTL_COMBOBOX + && ci->class != CTL_LISTBOX + && ci->class != CTL_SCROLLBAR))) { fprintf (e, " "); res_id_print (e, control->text, 1); @@ -2906,8 +2922,8 @@ test_rc_datablock_text (rc_uint_type length, const bfd_byte *data) for (i = 0, c = 0; i < length; i++) { if (! ISPRINT (data[i]) && data[i] != '\n' - && ! (data[i] == '\r' && (i + 1) < length && data[i + 1] == '\n') - && data[i] != '\t' + && ! (data[i] == '\r' && (i + 1) < length && data[i + 1] == '\n') + && data[i] != '\t' && ! (data[i] == 0 && (i + 1) != length)) { if (data[i] <= 7) @@ -2944,7 +2960,7 @@ write_rc_messagetable (FILE *e, rc_uint_type length, const bfd_byte *data) rc_uint_type m, i; mt = (const struct bin_messagetable *) data; - m = windres_get_32 (&wrtarget, mt->cblocks, length); + m = target_get_32 (mt->cblocks, length); if (length < (BIN_MESSAGETABLE_SIZE + m * BIN_MESSAGETABLE_BLOCK_SIZE)) { @@ -2956,9 +2972,9 @@ write_rc_messagetable (FILE *e, rc_uint_type length, const bfd_byte *data) rc_uint_type low, high, offset; const struct bin_messagetable_item *mti; - low = windres_get_32 (&wrtarget, mt->items[i].lowid, 4); - high = windres_get_32 (&wrtarget, mt->items[i].highid, 4); - offset = windres_get_32 (&wrtarget, mt->items[i].offset, 4); + low = windres_get_32 (&wrtarget, mt->items[i].lowid); + high = windres_get_32 (&wrtarget, mt->items[i].highid); + offset = windres_get_32 (&wrtarget, mt->items[i].offset); while (low <= high) { @@ -2969,8 +2985,8 @@ write_rc_messagetable (FILE *e, rc_uint_type length, const bfd_byte *data) break; } mti = (const struct bin_messagetable_item *) &data[offset]; - elen = windres_get_16 (&wrtarget, mti->length, 2); - flags = windres_get_16 (&wrtarget, mti->flags, 2); + elen = windres_get_16 (&wrtarget, mti->length); + flags = windres_get_16 (&wrtarget, mti->flags); if ((offset + elen) > length) { has_error = 1; @@ -3008,8 +3024,8 @@ write_rc_messagetable (FILE *e, rc_uint_type length, const bfd_byte *data) } static void -write_rc_datablock (FILE *e, rc_uint_type length, const bfd_byte *data, int has_next, - int hasblock, int show_comment) +write_rc_datablock (FILE *e, rc_uint_type length, const bfd_byte *data, + int has_next, int hasblock, int show_comment) { int plen; @@ -3031,23 +3047,23 @@ write_rc_datablock (FILE *e, rc_uint_type length, const bfd_byte *data, int has_ if (i < length && data[i] == '\n') ++i, ++c; ascii_print(e, (const char *) &data[i - c], c); - fprintf (e, "\""); + fprintf (e, "\""); if (i < length) fprintf (e, "\n"); } if (i == 0) - { + { indent (e, 2); fprintf (e, "\"\""); - } + } if (has_next) fprintf (e, ","); fprintf (e, "\n"); if (hasblock) fprintf (e, "END\n"); return; - } + } if (test_rc_datablock_unicode (length, data)) { rc_uint_type i, c; @@ -3057,20 +3073,20 @@ write_rc_datablock (FILE *e, rc_uint_type length, const bfd_byte *data, int has_ u = (const unichar *) &data[i]; indent (e, 2); - fprintf (e, "L\""); + fprintf (e, "L\""); for (c = 0; i < length && c < 160 && u[c] != '\n'; c++, i += 2) ; if (i < length && u[c] == '\n') i += 2, ++c; unicode_print (e, u, c); - fprintf (e, "\""); + fprintf (e, "\""); if (i < length) fprintf (e, "\n"); } if (i == 0) - { + { indent (e, 2); fprintf (e, "L\"\""); } @@ -3086,14 +3102,14 @@ write_rc_datablock (FILE *e, rc_uint_type length, const bfd_byte *data, int has_ } if (length != 0) - { + { rc_uint_type i, max_row; int first = 1; max_row = (show_comment ? 4 : 8); indent (e, 2); for (i = 0; i + 3 < length;) - { + { rc_uint_type k; rc_uint_type comment_start; @@ -3103,65 +3119,68 @@ write_rc_datablock (FILE *e, rc_uint_type length, const bfd_byte *data, int has_ indent (e, 2); for (k = 0; k < max_row && i + 3 < length; k++, i += 4) - { + { if (k == 0) - plen = fprintf (e, "0x%lxL", - (unsigned long) windres_get_32 (&wrtarget, data + i, length - i)); - else + plen = fprintf (e, "0x%lxL", + (unsigned long) target_get_32 (data + i, + length - i)); + else plen = fprintf (e, " 0x%lxL", - (unsigned long) windres_get_32 (&wrtarget, data + i, length - i)) - 1; + (unsigned long) target_get_32 (data + i, + length - i)) - 1; if (has_next || (i + 4) < length) - { + { if (plen>0 && plen < 11) indent (e, 11 - plen); fprintf (e, ","); - } - } + } + } if (show_comment) { fprintf (e, "\t/* "); - ascii_print (e, (const char *) &data[comment_start], i - comment_start); + ascii_print (e, (const char *) &data[comment_start], + i - comment_start); fprintf (e, ". */"); - } - fprintf (e, "\n"); - first = 0; - } + } + fprintf (e, "\n"); + first = 0; + } if (i + 1 < length) - { - if (! first) + { + if (! first) indent (e, 2); plen = fprintf (e, "0x%x", - (int) windres_get_16 (&wrtarget, data + i, length - i)); + (int) target_get_16 (data + i, length - i)); if (has_next || i + 2 < length) - { + { if (plen > 0 && plen < 11) indent (e, 11 - plen); fprintf (e, ","); - } + } if (show_comment) { fprintf (e, "\t/* "); ascii_print (e, (const char *) &data[i], 2); fprintf (e, ". */"); - } - fprintf (e, "\n"); - i += 2; - first = 0; - } + } + fprintf (e, "\n"); + i += 2; + first = 0; + } if (i < length) - { - if (! first) + { + if (! first) indent (e, 2); fprintf (e, "\""); ascii_print (e, (const char *) &data[i], 1); fprintf (e, "\""); if (has_next) - fprintf (e, ","); - fprintf (e, "\n"); - first = 0; - } + fprintf (e, ","); + fprintf (e, "\n"); + first = 0; + } } if (hasblock) fprintf (e, "END\n"); @@ -3214,9 +3233,9 @@ write_rc_rcdata (FILE *e, const rc_rcdata_item *rcdata, int ind) case RCDATA_BUFFER: write_rc_datablock (e, (rc_uint_type) ri->u.buffer.length, - (const bfd_byte *) ri->u.buffer.data, - ri->next != NULL, 0, -1); - break; + (const bfd_byte *) ri->u.buffer.data, + ri->next != NULL, 0, -1); + break; } if (ri->type != RCDATA_BUFFER) @@ -3257,7 +3276,7 @@ write_rc_stringtable (FILE *e, const rc_res_id *name, { fprintf (e, " %lu, ", (unsigned long) offset + i); unicode_print_quoted (e, stringtable->strings[i].string, - stringtable->strings[i].length); + stringtable->strings[i].length); fprintf (e, "\n"); } } @@ -3298,7 +3317,7 @@ write_rc_versioninfo (FILE *e, const rc_versioninfo *versioninfo) fprintf (e, " FILESUBTYPE 0x%x\n", (unsigned int) f->file_subtype); if (f->file_date_ms != 0 || f->file_date_ls != 0) fprintf (e, "/* Date: %u, %u. */\n", - (unsigned int) f->file_date_ms, (unsigned int) f->file_date_ls); + (unsigned int) f->file_date_ms, (unsigned int) f->file_date_ls); fprintf (e, "BEGIN\n"); @@ -3366,7 +3385,7 @@ rcdata_copy (const rc_rcdata_item *src, bfd_byte *dst) if (! src) return 0; switch (src->type) - { + { case RCDATA_WORD: if (dst) windres_put_16 (&wrtarget, dst, (rc_uint_type) src->u.word); diff --git a/binutils/resres.c b/binutils/resres.c index d96fb14..6505580 100644 --- a/binutils/resres.c +++ b/binutils/resres.c @@ -201,11 +201,11 @@ read_resource_entry (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax) /* Read additional resource header */ read_res_data (wrbfd, off, omax, &l, BIN_RES_INFO_SIZE); - resinfo.version = windres_get_32 (wrbfd, l.version, 4); - resinfo.memflags = windres_get_16 (wrbfd, l.memflags, 2); - resinfo.language = windres_get_16 (wrbfd, l.language, 2); - /* resinfo.version2 = windres_get_32 (wrbfd, l.version2, 4); */ - resinfo.characteristics = windres_get_32 (wrbfd, l.characteristics, 4); + resinfo.version = windres_get_32 (wrbfd, l.version); + resinfo.memflags = windres_get_16 (wrbfd, l.memflags); + resinfo.language = windres_get_16 (wrbfd, l.language); + /* resinfo.version2 = windres_get_32 (wrbfd, l.version2); */ + resinfo.characteristics = windres_get_32 (wrbfd, l.characteristics); off[0] = (off[0] + 3) & ~3; @@ -464,8 +464,8 @@ read_res_data_hdr (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax, fatal ("%s: unexpected end of file %ld/%ld", filename,(long) off[0], (long) omax); get_windres_bfd_content (wrbfd, &brh, off[0], BIN_RES_HDR_SIZE); - reshdr->data_size = windres_get_32 (wrbfd, brh.data_size, 4); - reshdr->header_size = windres_get_32 (wrbfd, brh.header_size, 4); + reshdr->data_size = windres_get_32 (wrbfd, brh.data_size); + reshdr->header_size = windres_get_32 (wrbfd, brh.header_size); off[0] += BIN_RES_HDR_SIZE; } @@ -542,12 +542,12 @@ read_res_id (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax, rc_res_id rc_uint_type len; read_res_data (wrbfd, off, omax, &bid, BIN_RES_ID - 2); - ord = (unsigned short) windres_get_16 (wrbfd, bid.sig, 2); + ord = (unsigned short) windres_get_16 (wrbfd, bid.sig); if (ord == 0xFFFF) /* an ordinal id */ { read_res_data (wrbfd, off, omax, bid.id, BIN_RES_ID - 2); id->named = 0; - id->u.id = windres_get_16 (wrbfd, bid.id, 2); + id->u.id = windres_get_16 (wrbfd, bid.id); } else /* named id */ @@ -575,7 +575,7 @@ read_unistring (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax, do { read_res_data (wrbfd, &soff, omax, d, sizeof (unichar)); - c = windres_get_16 (wrbfd, d, 2); + c = windres_get_16 (wrbfd, d); } while (c != 0); l = ((soff - off[0]) / sizeof (unichar)); @@ -585,7 +585,7 @@ read_unistring (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax, do { read_res_data (wrbfd, off, omax, d, sizeof (unichar)); - c = windres_get_16 (wrbfd, d, 2); + c = windres_get_16 (wrbfd, d); *p++ = c; } while (c != 0); diff --git a/binutils/windint.h b/binutils/windint.h index 3b950ac..10cf46e 100644 --- a/binutils/windint.h +++ b/binutils/windint.h @@ -1087,9 +1087,9 @@ extern void get_windres_bfd_content (windres_bfd *, void *, rc_uint_type, rc_uin extern void windres_put_8 (windres_bfd *, void *, rc_uint_type); extern void windres_put_16 (windres_bfd *, void *, rc_uint_type); extern void windres_put_32 (windres_bfd *, void *, rc_uint_type); -extern rc_uint_type windres_get_8 (windres_bfd *, const void *, rc_uint_type); -extern rc_uint_type windres_get_16 (windres_bfd *, const void *, rc_uint_type); -extern rc_uint_type windres_get_32 (windres_bfd *, const void *, rc_uint_type); +extern rc_uint_type windres_get_8 (windres_bfd *, const void *); +extern rc_uint_type windres_get_16 (windres_bfd *, const void *); +extern rc_uint_type windres_get_32 (windres_bfd *, const void *); extern void set_windres_bfd (windres_bfd *, bfd *, asection *, rc_uint_type); extern void set_windres_bfd_endianness (windres_bfd *, int); diff --git a/binutils/windres.c b/binutils/windres.c index b41353b..cfd306b 100644 --- a/binutils/windres.c +++ b/binutils/windres.c @@ -1210,23 +1210,15 @@ target_put_32 (void *p, rc_uint_type value) } static rc_uint_type -target_get_8 (const void *p, rc_uint_type length) +target_get_8 (const void *p) { - rc_uint_type ret; - - if (length < 1) - fatal ("Resource too small for getting 8-bit value."); - - ret = (rc_uint_type) *((const bfd_byte *) p); + rc_uint_type ret = *((const bfd_byte *) p); return ret & 0xff; } static rc_uint_type -target_get_16 (const void *p, rc_uint_type length) +target_get_16 (const void *p) { - if (length < 2) - fatal ("Resource too small for getting 16-bit value."); - if (target_is_bigendian) return bfd_getb16 (p); else @@ -1234,11 +1226,8 @@ target_get_16 (const void *p, rc_uint_type length) } static rc_uint_type -target_get_32 (const void *p, rc_uint_type length) +target_get_32 (const void *p) { - if (length < 4) - fatal ("Resource too small for getting 32-bit value."); - if (target_is_bigendian) return bfd_getb32 (p); else @@ -1304,14 +1293,12 @@ windres_put_32 (windres_bfd *wrbfd, void *data, rc_uint_type value) } rc_uint_type -windres_get_8 (windres_bfd *wrbfd, const void *data, rc_uint_type length) +windres_get_8 (windres_bfd *wrbfd, const void *data) { - if (length < 1) - fatal ("windres_get_8: unexpected eob."); switch (WR_KIND(wrbfd)) { case WR_KIND_TARGET: - return target_get_8 (data, length); + return target_get_8 (data); case WR_KIND_BFD: case WR_KIND_BFD_BIN_B: case WR_KIND_BFD_BIN_L: @@ -1323,14 +1310,12 @@ windres_get_8 (windres_bfd *wrbfd, const void *data, rc_uint_type length) } rc_uint_type -windres_get_16 (windres_bfd *wrbfd, const void *data, rc_uint_type length) +windres_get_16 (windres_bfd *wrbfd, const void *data) { - if (length < 2) - fatal ("windres_get_16: unexpected eob."); switch (WR_KIND(wrbfd)) { case WR_KIND_TARGET: - return target_get_16 (data, length); + return target_get_16 (data); case WR_KIND_BFD: case WR_KIND_BFD_BIN_B: return bfd_get_16 (WR_BFD(wrbfd), data); @@ -1343,14 +1328,12 @@ windres_get_16 (windres_bfd *wrbfd, const void *data, rc_uint_type length) } rc_uint_type -windres_get_32 (windres_bfd *wrbfd, const void *data, rc_uint_type length) +windres_get_32 (windres_bfd *wrbfd, const void *data) { - if (length < 4) - fatal ("windres_get_32: unexpected eob."); switch (WR_KIND(wrbfd)) { case WR_KIND_TARGET: - return target_get_32 (data, length); + return target_get_32 (data); case WR_KIND_BFD: case WR_KIND_BFD_BIN_B: return bfd_get_32 (WR_BFD(wrbfd), data); diff --git a/gas/input-scrub.c b/gas/input-scrub.c index 2e0ce83..93d1e8e 100644 --- a/gas/input-scrub.c +++ b/gas/input-scrub.c @@ -150,6 +150,21 @@ input_scrub_reinit (void) memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE); } +/* Finish off old buffers. */ + +static void +input_scrub_free (void) +{ + if (sb_index != (size_t) -1) + { + sb_kill (&from_sb); + sb_index = -1; + } + free (buffer_start); + buffer_start = NULL; + input_file_end (); +} + /* Push the state of input reading and scrubbing so that we can #include. The return value is a 'void *' (fudged for old compilers) to a save area, which can be restored by passing it to input_scrub_pop(). */ @@ -188,7 +203,7 @@ input_scrub_pop (struct input_save *saved) { char *saved_position; - input_scrub_end (); /* Finish off old buffer */ + input_scrub_free (); input_file_pop (saved->input_file_save); saved_position = saved->saved_position; @@ -241,12 +256,9 @@ input_scrub_begin (void) void input_scrub_end (void) { - if (buffer_start) - { - free (buffer_start); - buffer_start = 0; - input_file_end (); - } + while (next_saved_file != NULL) + input_scrub_pop (next_saved_file); + input_scrub_free (); } /* Start reading input from a new file. @@ -341,7 +353,6 @@ input_scrub_next_buffer (char **bufp) { if (sb_index >= from_sb.len) { - sb_kill (&from_sb); if (from_sb_expansion == expanding_macro) { cond_finish_check (macro_nest); diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y index e7317b7..d4ab98c 100644 --- a/gdb/cp-name-parser.y +++ b/gdb/cp-name-parser.y @@ -2047,9 +2047,11 @@ cp_demangled_name_to_comp (const char *demangled_name, auto result = std::make_unique<demangle_parse_info> (); cpname_state state (demangled_name, result.get ()); - scoped_restore restore_yydebug = make_scoped_restore (&yydebug, - parser_debug); - + /* Note that we can't set yydebug here, as is done in the other + parsers. Bison implements yydebug as a global, even with a pure + parser, and this parser is run from worker threads. So, changing + yydebug causes TSan reports. If you need to debug this parser, + debug gdb and set the global from the outer gdb. */ if (yyparse (&state)) { if (state.global_errmsg && errmsg) diff --git a/gdb/doc/guile.texi b/gdb/doc/guile.texi index c6808ef..c6d889f 100644 --- a/gdb/doc/guile.texi +++ b/gdb/doc/guile.texi @@ -3899,6 +3899,9 @@ Return string to change terminal's color to this. If @var{is_foreground} is @code{#t}, then the returned sequence will change foreground color. Otherwise, the returned sequence will change background color. + +If styling is currently disabled (@pxref{Output Styling,,@kbd{set style +enabled}}), then this procedure will return an empty string. @end deffn When color is initialized, its color space must be specified. The diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index afbd62f..7bb6503 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -7101,6 +7101,9 @@ Returns string to change terminal's color to this. If @var{is_foreground} is @code{True}, then the returned sequence will change foreground color. Otherwise, the returned sequence will change background color. + +If styling is currently disabled (@pxref{Output Styling,,@kbd{set style +enabled}}), then this method will return an empty string. @end defun When color is initialized, its color space must be specified. The diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h index 5338dfe..9f76789 100644 --- a/gdb/dwarf2/cu.h +++ b/gdb/dwarf2/cu.h @@ -27,6 +27,8 @@ #include "gdbsupport/unordered_set.h" #include "dwarf2/die.h" +struct field_info; + /* Type used for delaying computation of method physnames. See comments for compute_delayed_physnames. */ struct delayed_method_info @@ -399,6 +401,15 @@ public: .debug_str_offsets section (8 or 4, depending on the address size). */ std::optional<ULONGEST> str_offsets_base; + /* We may encounter a DIE where a property refers to a field in some + outer type. For example, in Ada, an array length may depend on a + field in some outer record. In this case, we need to be able to + stash a pointer to the 'struct field' into the appropriate + dynamic property baton. However, the fields aren't created until + the type has been fully processed, so we need a temporary + back-link to this object. */ + struct field_info *field_info = nullptr; + /* Mark used when releasing cached dies. */ bool m_mark : 1; diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c index e1a5fdd..fa1b4eb 100644 --- a/gdb/dwarf2/loc.c +++ b/gdb/dwarf2/loc.c @@ -1732,11 +1732,10 @@ dwarf2_evaluate_property (const dynamic_prop *prop, *value = prop->const_val (); return true; - case PROP_ADDR_OFFSET: + case PROP_FIELD: { const dwarf2_property_baton *baton = prop->baton (); const struct property_addr_info *pinfo; - struct value *val; for (pinfo = addr_stack; pinfo != NULL; pinfo = pinfo->next) { @@ -1747,14 +1746,40 @@ dwarf2_evaluate_property (const dynamic_prop *prop, } if (pinfo == NULL) error (_("cannot find reference address for offset property")); - if (pinfo->valaddr.data () != NULL) - val = value_from_contents - (baton->offset_info.type, - pinfo->valaddr.data () + baton->offset_info.offset); - else - val = value_at (baton->offset_info.type, - pinfo->addr + baton->offset_info.offset); - *value = value_as_address (val); + + struct field resolved_field = *baton->field; + resolve_dynamic_field (resolved_field, pinfo, initial_frame); + + /* Storage for memory if we need to read it. */ + gdb::byte_vector memory; + const gdb_byte *bytes = pinfo->valaddr.data (); + if (bytes == nullptr) + { + int bitpos = resolved_field.loc_bitpos (); + int bitsize = resolved_field.bitsize (); + if (bitsize == 0) + bitsize = check_typedef (resolved_field.type ())->length () * 8; + + /* Read just the minimum number of bytes needed to satisfy + unpack_field_as_long. So, update the resolved field's + starting offset to remove any unnecessary leading + bytes. */ + int byte_offset = bitpos / 8; + + bitpos %= 8; + resolved_field.set_loc_bitpos (bitpos); + + /* Make sure to include any remaining bit offset in the + size computation, in case the value straddles a + byte. */ + int byte_length = align_up (bitsize + bitpos, 8) / 8; + memory.resize (byte_length); + + read_memory (pinfo->addr + byte_offset, memory.data (), + byte_length); + bytes = memory.data (); + } + *value = unpack_field_as_long (bytes, &resolved_field); return true; } diff --git a/gdb/dwarf2/loc.h b/gdb/dwarf2/loc.h index 30c528b..ebe5c31 100644 --- a/gdb/dwarf2/loc.h +++ b/gdb/dwarf2/loc.h @@ -99,7 +99,7 @@ struct property_addr_info /* If not NULL, a pointer to the info for the object containing the object described by this node. */ - struct property_addr_info *next; + const property_addr_info *next; }; /* Converts a dynamic property into a static one. FRAME is the frame in which @@ -167,6 +167,9 @@ struct dwarf2_locexpr_baton directly. */ bool is_reference; + /* True if this object is actually a dwarf2_field_location_baton. */ + bool is_field_location; + /* The objfile that was used when creating this. */ dwarf2_per_objfile *per_objfile; @@ -175,6 +178,23 @@ struct dwarf2_locexpr_baton dwarf2_per_cu *per_cu; }; +/* If the DWARF location for a field used DW_AT_bit_size, then an + object of this type is created to represent the field location. + This is then used to apply the bit offset after computing the + field's byte offset. Objects of this type always set the + 'is_field_location' member in dwarf2_locexpr_baton. See also + apply_bit_offset_to_field. */ + +struct dwarf2_field_location_baton : public dwarf2_locexpr_baton +{ + /* The bit offset, coming from DW_AT_bit_offset. */ + LONGEST bit_offset; + + /* The DW_AT_byte_size of the field. If no explicit byte size was + specified, this is 0. */ + LONGEST explicit_byte_size; +}; + struct dwarf2_loclist_baton { /* The initial base address for the location list, based on the compilation @@ -202,23 +222,6 @@ struct dwarf2_loclist_baton unsigned char dwarf_version; }; -/* The baton used when a dynamic property is an offset to a parent - type. This can be used, for instance, then the bound of an array - inside a record is determined by the value of another field inside - that record. */ - -struct dwarf2_offset_baton -{ - /* The offset from the parent type where the value of the property - is stored. In the example provided above, this would be the offset - of the field being used as the array bound. */ - LONGEST offset; - - /* The type of the object whose property is dynamic. In the example - provided above, this would the array's index type. */ - struct type *type; -}; - /* A dynamic property is either expressed as a single location expression or a location list. If the property is an indirection, pointing to another die, keep track of the targeted type in PROPERTY_TYPE. @@ -241,8 +244,8 @@ struct dwarf2_property_baton /* Location list to be evaluated in the context of PROPERTY_TYPE. */ struct dwarf2_loclist_baton loclist; - /* The location is an offset to PROPERTY_TYPE. */ - struct dwarf2_offset_baton offset_info; + /* The location is stored in a field of PROPERTY_TYPE. */ + struct field *field; }; }; diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 6848f63..71fa793 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -698,6 +698,12 @@ struct field_info we're reading. */ std::vector<variant_part_builder> variant_parts; + /* All the field batons that must be updated. This is only used + when a type's property depends on a field of this structure; for + example in Ada when an array's length may come from a field of an + enclosing record. */ + gdb::unordered_map<dwarf2_property_baton *, sect_offset> field_batons; + /* Return the total number of fields (including baseclasses). */ int nfields () const { @@ -8738,7 +8744,8 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) struct dwarf2_locexpr_baton *dlbaton; struct dwarf_block *block = attr->as_block (); - dlbaton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_locexpr_baton); + dlbaton = OBSTACK_ZALLOC (&objfile->objfile_obstack, + struct dwarf2_locexpr_baton); dlbaton->data = block->data; dlbaton->size = block->size; dlbaton->per_objfile = per_objfile; @@ -9861,54 +9868,6 @@ dwarf2_access_attribute (struct die_info *die, struct dwarf2_cu *cu) } } -/* Look for DW_AT_data_member_location or DW_AT_data_bit_offset. Set - *OFFSET to the byte offset. If the attribute was not found return - 0, otherwise return 1. If it was found but could not properly be - handled, set *OFFSET to 0. */ - -static int -handle_member_location (struct die_info *die, struct dwarf2_cu *cu, - LONGEST *offset) -{ - struct attribute *attr; - - attr = dwarf2_attr (die, DW_AT_data_member_location, cu); - if (attr != NULL) - { - *offset = 0; - CORE_ADDR temp; - - /* Note that we do not check for a section offset first here. - This is because DW_AT_data_member_location is new in DWARF 4, - so if we see it, we can assume that a constant form is really - a constant and not a section offset. */ - if (attr->form_is_constant ()) - *offset = attr->unsigned_constant ().value_or (0); - else if (attr->form_is_section_offset ()) - dwarf2_complex_location_expr_complaint (); - else if (attr->form_is_block () - && decode_locdesc (attr->as_block (), cu, &temp)) - { - *offset = temp; - } - else - dwarf2_complex_location_expr_complaint (); - - return 1; - } - else - { - attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu); - if (attr != nullptr) - { - *offset = attr->unsigned_constant ().value_or (0); - return 1; - } - } - - return 0; -} - /* Look for DW_AT_data_member_location or DW_AT_data_bit_offset and store the results in FIELD. */ @@ -9921,6 +9880,25 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu, attr = dwarf2_attr (die, DW_AT_data_member_location, cu); if (attr != NULL) { + bool has_bit_offset = false; + LONGEST bit_offset = 0; + LONGEST anonymous_size = 0; + + attribute *attr2 = dwarf2_attr (die, DW_AT_bit_offset, cu); + if (attr2 != nullptr && attr2->form_is_constant ()) + { + has_bit_offset = true; + bit_offset = attr2->unsigned_constant ().value_or (0); + attr2 = dwarf2_attr (die, DW_AT_byte_size, cu); + if (attr2 != nullptr && attr2->form_is_constant ()) + { + /* The size of the anonymous object containing + the bit field is explicit, so use the + indicated size (in bytes). */ + anonymous_size = attr2->unsigned_constant ().value_or (0); + } + } + if (attr->form_is_constant ()) { LONGEST offset = attr->unsigned_constant ().value_or (0); @@ -9938,9 +9916,9 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu, } field->set_loc_bitpos (offset * bits_per_byte); + if (has_bit_offset) + apply_bit_offset_to_field (*field, bit_offset, anonymous_size); } - else if (attr->form_is_section_offset ()) - dwarf2_complex_location_expr_complaint (); else if (attr->form_is_block ()) { CORE_ADDR offset; @@ -9950,9 +9928,20 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu, { dwarf2_per_objfile *per_objfile = cu->per_objfile; struct objfile *objfile = per_objfile->objfile; - struct dwarf2_locexpr_baton *dlbaton - = XOBNEW (&objfile->objfile_obstack, - struct dwarf2_locexpr_baton); + struct dwarf2_locexpr_baton *dlbaton; + if (has_bit_offset) + { + dwarf2_field_location_baton *flbaton + = OBSTACK_ZALLOC (&objfile->objfile_obstack, + dwarf2_field_location_baton); + flbaton->is_field_location = true; + flbaton->bit_offset = bit_offset; + flbaton->explicit_byte_size = anonymous_size; + dlbaton = flbaton; + } + else + dlbaton = OBSTACK_ZALLOC (&objfile->objfile_obstack, + struct dwarf2_locexpr_baton); dlbaton->data = attr->as_block ()->data; dlbaton->size = attr->as_block ()->size; /* When using this baton, we want to compute the address @@ -9966,7 +9955,8 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu, } } else - dwarf2_complex_location_expr_complaint (); + complaint (_("Unsupported form %s for DW_AT_data_member_location"), + dwarf_form_name (attr->form)); } else { @@ -9982,8 +9972,6 @@ static void dwarf2_add_field (struct field_info *fip, struct die_info *die, struct dwarf2_cu *cu) { - struct objfile *objfile = cu->per_objfile->objfile; - struct gdbarch *gdbarch = objfile->arch (); struct nextfield *new_field; struct attribute *attr; struct field *fp; @@ -10047,50 +10035,6 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, /* Get bit offset of field. */ handle_member_location (die, cu, fp); - attr = dwarf2_attr (die, DW_AT_bit_offset, cu); - if (attr != nullptr && attr->form_is_constant ()) - { - ULONGEST bit_offset = attr->unsigned_constant ().value_or (0); - if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) - { - /* For big endian bits, the DW_AT_bit_offset gives the - additional bit offset from the MSB of the containing - anonymous object to the MSB of the field. We don't - have to do anything special since we don't need to - know the size of the anonymous object. */ - fp->set_loc_bitpos (fp->loc_bitpos () + bit_offset); - } - else - { - /* For little endian bits, compute the bit offset to the - MSB of the anonymous object, subtract off the number of - bits from the MSB of the field to the MSB of the - object, and then subtract off the number of bits of - the field itself. The result is the bit offset of - the LSB of the field. */ - int anonymous_size; - - attr = dwarf2_attr (die, DW_AT_byte_size, cu); - if (attr != nullptr && attr->form_is_constant ()) - { - /* The size of the anonymous object containing - the bit field is explicit, so use the - indicated size (in bytes). */ - anonymous_size = attr->unsigned_constant ().value_or (0); - } - else - { - /* The size of the anonymous object containing - the bit field must be inferred from the type - attribute of the data member containing the - bit field. */ - anonymous_size = fp->type ()->length (); - } - fp->set_loc_bitpos (fp->loc_bitpos () - + anonymous_size * bits_per_byte - - bit_offset - fp->bitsize ()); - } - } /* Get name of field. */ fieldname = dwarf2_name (die, cu); @@ -11269,6 +11213,56 @@ handle_struct_member_die (struct die_info *child_die, struct type *type, handle_variant (child_die, type, fi, template_args, cu); } +/* Create a property baton for a field of the struct type currently + being processed. OFFSET is the DIE offset of the field in the + structure. If OFFSET is found among the fields that have already + been seen, then a new property baton is allocated on the objfile + obstack and returned. The baton isn't fully filled in -- it will + be post-processed once the fields are finally created; see + update_field_batons. If OFFSET is not found, NULL is returned. */ + +static dwarf2_property_baton * +find_field_create_baton (dwarf2_cu *cu, sect_offset offset) +{ + field_info *fi = cu->field_info; + /* Defensive programming in case we see unusual DWARF. */ + if (fi == nullptr) + return nullptr; + for (const auto &fld : fi->fields) + if (fld.offset == offset) + { + dwarf2_property_baton *result + = XOBNEW (&cu->per_objfile->objfile->objfile_obstack, + struct dwarf2_property_baton); + fi->field_batons[result] = offset; + return result; + } + return nullptr; +} + +/* Update all the stored field property batons. FI is the field info + for the structure being created. TYPE is the corresponding struct + type with its fields already filled in. This fills in the correct + field for each baton that was stored while processing this + type. */ + +static void +update_field_batons (field_info *fi, struct type *type) +{ + int n_bases = fi->baseclasses.size (); + for (auto &[baton, offset] : fi->field_batons) + { + for (int i = 0; i < fi->fields.size (); ++i) + { + if (fi->fields[i].offset == offset) + { + baton->field = &type->field (n_bases + i); + break; + } + } + } +} + /* Finish creating a structure or union type, including filling in its members and creating a symbol for it. This function also handles Fortran namelist variables, their items or members and creating a symbol for @@ -11290,6 +11284,9 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) struct field_info fi; std::vector<struct symbol *> template_args; + scoped_restore save_field_info + = make_scoped_restore (&cu->field_info, &fi); + for (die_info *child_die : die->children ()) handle_struct_member_die (child_die, type, &fi, &template_args, cu); @@ -11311,7 +11308,11 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) /* Attach fields and member functions to the type. */ if (fi.nfields () > 0) - dwarf2_attach_fields_to_type (&fi, type, cu); + { + dwarf2_attach_fields_to_type (&fi, type, cu); + update_field_batons (&fi, type); + } + if (!fi.fnfieldlists.empty ()) { dwarf2_attach_fn_fields_to_type (&fi, type, cu); @@ -12262,7 +12263,8 @@ mark_common_block_symbol_computed (struct symbol *sym, gdb_assert (member_loc->form_is_block () || member_loc->form_is_constant ()); - baton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_locexpr_baton); + baton = OBSTACK_ZALLOC (&objfile->objfile_obstack, + struct dwarf2_locexpr_baton); baton->per_objfile = per_objfile; baton->per_cu = cu->per_cu; gdb_assert (baton->per_cu); @@ -13165,7 +13167,7 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu) a given gmp_mpz given an attribute. */ static void -get_mpz (struct dwarf2_cu *cu, gdb_mpz *value, struct attribute *attr) +get_mpz_for_rational (dwarf2_cu *cu, gdb_mpz *value, attribute *attr) { /* GCC will sometimes emit a 16-byte constant value as a DWARF location expression that pushes an implicit value. */ @@ -13199,10 +13201,11 @@ get_mpz (struct dwarf2_cu *cu, gdb_mpz *value, struct attribute *attr) ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE, true); } - else if (attr->form_is_strictly_unsigned ()) - *value = gdb_mpz (attr->as_unsigned ()); else - *value = gdb_mpz (attr->signed_constant ().value_or (1)); + { + /* Rational constants for Ada are always unsigned. */ + *value = gdb_mpz (attr->unsigned_constant ().value_or (1)); + } } /* Assuming DIE is a rational DW_TAG_constant, read the DIE's @@ -13231,8 +13234,8 @@ get_dwarf2_rational_constant (struct die_info *die, struct dwarf2_cu *cu, if (num_attr == nullptr || denom_attr == nullptr) return; - get_mpz (cu, numerator, num_attr); - get_mpz (cu, denominator, denom_attr); + get_mpz_for_rational (cu, numerator, num_attr); + get_mpz_for_rational (cu, denominator, denom_attr); } /* Same as get_dwarf2_rational_constant, but extracting an unsigned @@ -13924,17 +13927,14 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die, case DW_AT_data_member_location: case DW_AT_data_bit_offset: { - LONGEST offset; - - if (!handle_member_location (target_die, target_cu, &offset)) + baton = find_field_create_baton (cu, target_die->sect_off); + if (baton == nullptr) return 0; - baton = XOBNEW (obstack, struct dwarf2_property_baton); baton->property_type = read_type_die (target_die->parent, - target_cu); - baton->offset_info.offset = offset; - baton->offset_info.type = die_type (target_die, target_cu); - prop->set_addr_offset (baton); + target_cu); + baton->field = nullptr; + prop->set_field (baton); break; } } @@ -17234,7 +17234,7 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type, /* Symbols of this form are reasonably rare, so we just piggyback on the existing location code rather than writing a new implementation of symbol_computed_ops. */ - *baton = XOBNEW (obstack, struct dwarf2_locexpr_baton); + *baton = OBSTACK_ZALLOC (obstack, struct dwarf2_locexpr_baton); (*baton)->per_objfile = per_objfile; (*baton)->per_cu = cu->per_cu; gdb_assert ((*baton)->per_cu); @@ -19185,7 +19185,8 @@ dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym, { struct dwarf2_locexpr_baton *baton; - baton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_locexpr_baton); + baton = OBSTACK_ZALLOC (&objfile->objfile_obstack, + struct dwarf2_locexpr_baton); baton->per_objfile = per_objfile; baton->per_cu = cu->per_cu; gdb_assert (baton->per_cu); diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 5713eac..a241223 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -902,7 +902,7 @@ operator== (const dynamic_prop &l, const dynamic_prop &r) return true; case PROP_CONST: return l.const_val () == r.const_val (); - case PROP_ADDR_OFFSET: + case PROP_FIELD: case PROP_LOCEXPR: case PROP_LOCLIST: return l.baton () == r.baton (); @@ -2146,7 +2146,7 @@ is_dynamic_type (struct type *type) } static struct type *resolve_dynamic_type_internal - (struct type *type, struct property_addr_info *addr_stack, + (struct type *type, const property_addr_info *addr_stack, const frame_info_ptr &frame, bool top_level); /* Given a dynamic range type (dyn_range_type) and a stack of @@ -2167,7 +2167,7 @@ static struct type *resolve_dynamic_type_internal static struct type * resolve_dynamic_range (struct type *dyn_range_type, - struct property_addr_info *addr_stack, + const property_addr_info *addr_stack, const frame_info_ptr &frame, int rank, bool resolve_p = true) { @@ -2269,7 +2269,7 @@ resolve_dynamic_range (struct type *dyn_range_type, static struct type * resolve_dynamic_array_or_string_1 (struct type *type, - struct property_addr_info *addr_stack, + const property_addr_info *addr_stack, const frame_info_ptr &frame, int rank, bool resolve_p) { @@ -2397,7 +2397,7 @@ resolve_dynamic_array_or_string_1 (struct type *type, static struct type * resolve_dynamic_array_or_string (struct type *type, - struct property_addr_info *addr_stack, + const property_addr_info *addr_stack, const frame_info_ptr &frame) { CORE_ADDR value; @@ -2490,7 +2490,7 @@ resolve_dynamic_array_or_string (struct type *type, static struct type * resolve_dynamic_union (struct type *type, - struct property_addr_info *addr_stack, + const property_addr_info *addr_stack, const frame_info_ptr &frame) { struct type *resolved_type; @@ -2534,7 +2534,7 @@ variant::matches (ULONGEST value, bool is_unsigned) const static void compute_variant_fields_inner (struct type *type, - struct property_addr_info *addr_stack, + const property_addr_info *addr_stack, const variant_part &part, std::vector<bool> &flags); @@ -2549,7 +2549,7 @@ compute_variant_fields_inner (struct type *type, static void compute_variant_fields_recurse (struct type *type, - struct property_addr_info *addr_stack, + const property_addr_info *addr_stack, const variant &variant, std::vector<bool> &flags, bool enabled) @@ -2581,7 +2581,7 @@ compute_variant_fields_recurse (struct type *type, static void compute_variant_fields_inner (struct type *type, - struct property_addr_info *addr_stack, + const property_addr_info *addr_stack, const variant_part &part, std::vector<bool> &flags) { @@ -2650,7 +2650,7 @@ compute_variant_fields_inner (struct type *type, static void compute_variant_fields (struct type *type, struct type *resolved_type, - struct property_addr_info *addr_stack, + const property_addr_info *addr_stack, const gdb::array_view<variant_part> &parts) { /* Assume all fields are included by default. */ @@ -2676,13 +2676,113 @@ compute_variant_fields (struct type *type, } } +/* See gdbtypes.h. */ + +void +apply_bit_offset_to_field (struct field &field, LONGEST bit_offset, + LONGEST explicit_byte_size) +{ + struct type *field_type = field.type (); + struct gdbarch *gdbarch = field_type->arch (); + LONGEST current_bitpos = field.loc_bitpos (); + + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + { + /* For big endian bits, the DW_AT_bit_offset gives the + additional bit offset from the MSB of the containing + anonymous object to the MSB of the field. We don't + have to do anything special since we don't need to + know the size of the anonymous object. */ + field.set_loc_bitpos (current_bitpos + bit_offset); + } + else + { + /* For little endian bits, compute the bit offset to the + MSB of the anonymous object, subtract off the number of + bits from the MSB of the field to the MSB of the + object, and then subtract off the number of bits of + the field itself. The result is the bit offset of + the LSB of the field. */ + LONGEST object_size = explicit_byte_size; + if (object_size == 0) + object_size = field_type->length (); + + field.set_loc_bitpos (current_bitpos + + 8 * object_size + - bit_offset + - field.bitsize ()); + } +} + +/* See gdbtypes.h. */ + +void +resolve_dynamic_field (struct field &field, + const property_addr_info *addr_stack, + const frame_info_ptr &frame) +{ + gdb_assert (!field.is_static ()); + + if (field.loc_kind () == FIELD_LOC_KIND_DWARF_BLOCK) + { + dwarf2_locexpr_baton *field_loc + = field.loc_dwarf_block (); + + struct dwarf2_property_baton baton; + baton.property_type = lookup_pointer_type (field.type ()); + baton.locexpr = *field_loc; + + struct dynamic_prop prop; + prop.set_locexpr (&baton); + + CORE_ADDR vals[1] = {addr_stack->addr}; + CORE_ADDR addr; + if (dwarf2_evaluate_property (&prop, frame, addr_stack, &addr, vals)) + { + field.set_loc_bitpos (TARGET_CHAR_BIT * (addr - addr_stack->addr)); + + if (field_loc->is_field_location) + { + dwarf2_field_location_baton *fl_baton + = static_cast<dwarf2_field_location_baton *> (field_loc); + apply_bit_offset_to_field (field, fl_baton->bit_offset, + fl_baton->explicit_byte_size); + } + } + } + + /* As we know this field is not a static field, the field's + field_loc_kind should be FIELD_LOC_KIND_BITPOS. Verify + this is the case, but only trigger a simple error rather + than an internal error if that fails. While failing + that verification indicates a bug in our code, the error + is not severe enough to suggest to the user he stops + his debugging session because of it. */ + if (field.loc_kind () != FIELD_LOC_KIND_BITPOS) + error (_("Cannot determine struct field location" + " (invalid location kind)")); + + struct property_addr_info pinfo; + pinfo.type = check_typedef (field.type ()); + size_t offset = field.loc_bitpos () / TARGET_CHAR_BIT; + pinfo.valaddr = addr_stack->valaddr; + if (!pinfo.valaddr.empty ()) + pinfo.valaddr = pinfo.valaddr.slice (offset); + pinfo.addr = addr_stack->addr + offset; + pinfo.next = addr_stack; + + field.set_type (resolve_dynamic_type_internal (field.type (), + &pinfo, frame, false)); + gdb_assert (field.loc_kind () == FIELD_LOC_KIND_BITPOS); +} + /* Resolve dynamic bounds of members of the struct TYPE to static bounds. ADDR_STACK is a stack of struct property_addr_info to be used if needed during the dynamic resolution. */ static struct type * resolve_dynamic_struct (struct type *type, - struct property_addr_info *addr_stack, + const property_addr_info *addr_stack, const frame_info_ptr &frame) { struct type *resolved_type; @@ -2710,52 +2810,11 @@ resolve_dynamic_struct (struct type *type, for (i = 0; i < resolved_type->num_fields (); ++i) { unsigned new_bit_length; - struct property_addr_info pinfo; if (resolved_type->field (i).is_static ()) continue; - if (resolved_type->field (i).loc_kind () == FIELD_LOC_KIND_DWARF_BLOCK) - { - struct dwarf2_property_baton baton; - baton.property_type - = lookup_pointer_type (resolved_type->field (i).type ()); - baton.locexpr = *resolved_type->field (i).loc_dwarf_block (); - - struct dynamic_prop prop; - prop.set_locexpr (&baton); - - CORE_ADDR addr; - if (dwarf2_evaluate_property (&prop, frame, addr_stack, &addr, - {addr_stack->addr})) - resolved_type->field (i).set_loc_bitpos - (TARGET_CHAR_BIT * (addr - addr_stack->addr)); - } - - /* As we know this field is not a static field, the field's - field_loc_kind should be FIELD_LOC_KIND_BITPOS. Verify - this is the case, but only trigger a simple error rather - than an internal error if that fails. While failing - that verification indicates a bug in our code, the error - is not severe enough to suggest to the user he stops - his debugging session because of it. */ - if (resolved_type->field (i).loc_kind () != FIELD_LOC_KIND_BITPOS) - error (_("Cannot determine struct field location" - " (invalid location kind)")); - - pinfo.type = check_typedef (resolved_type->field (i).type ()); - size_t offset = resolved_type->field (i).loc_bitpos () / TARGET_CHAR_BIT; - pinfo.valaddr = addr_stack->valaddr; - if (!pinfo.valaddr.empty ()) - pinfo.valaddr = pinfo.valaddr.slice (offset); - pinfo.addr = addr_stack->addr + offset; - pinfo.next = addr_stack; - - resolved_type->field (i).set_type - (resolve_dynamic_type_internal (resolved_type->field (i).type (), - &pinfo, frame, false)); - gdb_assert (resolved_type->field (i).loc_kind () - == FIELD_LOC_KIND_BITPOS); + resolve_dynamic_field (resolved_type->field (i), addr_stack, frame); new_bit_length = resolved_type->field (i).loc_bitpos (); if (resolved_type->field (i).bitsize () != 0) @@ -2797,7 +2856,7 @@ resolve_dynamic_struct (struct type *type, static struct type * resolve_dynamic_type_internal (struct type *type, - struct property_addr_info *addr_stack, + const property_addr_info *addr_stack, const frame_info_ptr &frame, bool top_level) { diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 5ee9deb..67b4bf0 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -259,7 +259,7 @@ enum dynamic_prop_kind { PROP_UNDEFINED, /* Not defined. */ PROP_CONST, /* Constant. */ - PROP_ADDR_OFFSET, /* Address offset. */ + PROP_FIELD, /* Field of a type. */ PROP_LOCEXPR, /* Location expression. */ PROP_LOCLIST, /* Location list. */ PROP_VARIANT_PARTS, /* Variant parts. */ @@ -347,7 +347,7 @@ struct dynamic_prop { gdb_assert (m_kind == PROP_LOCEXPR || m_kind == PROP_LOCLIST - || m_kind == PROP_ADDR_OFFSET); + || m_kind == PROP_FIELD); return m_data.baton; } @@ -364,9 +364,9 @@ struct dynamic_prop m_data.baton = baton; } - void set_addr_offset (const dwarf2_property_baton *baton) + void set_field (const dwarf2_property_baton *baton) { - m_kind = PROP_ADDR_OFFSET; + m_kind = PROP_FIELD; m_data.baton = baton; } @@ -2629,6 +2629,41 @@ extern struct type *resolve_dynamic_type "dynamic". */ extern bool is_dynamic_type (struct type *type); +/* Resolve any dynamic components of FIELD. FIELD is updated. + ADDR_STACK and FRAME are used where necessary to supply information + for the resolution process; see resolve_dynamic_type. + Specifically, after calling this, the field's bit position will be + a constant, and the field's type will not have dynamic properties. + + This function assumes that FIELD is not a static field. */ + +extern void resolve_dynamic_field (struct field &field, + const struct property_addr_info *addr_stack, + const frame_info_ptr &frame); + +/* A helper function that handles the DWARF semantics for + DW_AT_bit_offset. + + DWARF 3 specified DW_AT_bit_offset in a funny way, making it simple + to use on big-endian targets but somewhat difficult for + little-endian. This function handles the logic here. + + While DW_AT_bit_offset was deprecated in DWARF 4 (and removed + entirely from DWARF 5), it is still useful because it is the only + way to describe a field that appears at a non-constant bit + offset. + + FIELD is updated in-place. It is assumed that FIELD already has a + constant bit position. BIT_OFFSET is the value of the + DW_AT_bit_offset attribute, and EXPLICIT_BYTE_SIZE is either the + value of a DW_AT_byte_size from the field's DIE -- indicating an + explicit size of the enclosing anonymous object -- or it may be 0, + indicating that the field's type size should be used. */ + +extern void apply_bit_offset_to_field (struct field &field, + LONGEST bit_offset, + LONGEST explicit_byte_size); + extern struct type *check_typedef (struct type *); extern void check_stub_method_group (struct type *, int); diff --git a/gdb/guile/scm-color.c b/gdb/guile/scm-color.c index 4850575..cde22e5 100644 --- a/gdb/guile/scm-color.c +++ b/gdb/guile/scm-color.c @@ -24,6 +24,7 @@ #include "language.h" #include "arch-utils.h" #include "guile-internal.h" +#include "cli/cli-style.h" /* A GDB color. */ @@ -354,8 +355,14 @@ gdbscm_color_escape_sequence (SCM self, SCM is_fg_scm) const ui_file_style::color &color = coscm_get_color (self); SCM_ASSERT_TYPE (gdbscm_is_bool (is_fg_scm), is_fg_scm, SCM_ARG2, FUNC_NAME, _("boolean")); - bool is_fg = gdbscm_is_true (is_fg_scm); - std::string s = color.to_ansi (is_fg); + + std::string s; + if (term_cli_styling ()) + { + bool is_fg = gdbscm_is_true (is_fg_scm); + s = color.to_ansi (is_fg); + } + return gdbscm_scm_from_host_string (s.c_str (), s.size ()); } diff --git a/gdb/python/py-color.c b/gdb/python/py-color.c index e208506..3bbd22d 100644 --- a/gdb/python/py-color.c +++ b/gdb/python/py-color.c @@ -21,6 +21,7 @@ #include "python-internal.h" #include "py-color.h" #include "cli/cli-decode.h" +#include "cli/cli-style.h" /* Colorspace constants and their values. */ static struct { @@ -152,8 +153,12 @@ colorpy_escape_sequence (PyObject *self, PyObject *args, PyObject *kwargs) /* The argument parsing ensures we have a bool. */ gdb_assert (PyBool_Check (is_fg_obj)); - bool is_fg = is_fg_obj == Py_True; - std::string s = gdbpy_get_color (self).to_ansi (is_fg); + std::string s; + if (term_cli_styling ()) + { + bool is_fg = is_fg_obj == Py_True; + s = gdbpy_get_color (self).to_ansi (is_fg); + } return host_string_to_python_string (s.c_str ()).release (); } diff --git a/gdb/testsuite/gdb.ada/dyn-bit-offset.exp b/gdb/testsuite/gdb.ada/dyn-bit-offset.exp new file mode 100644 index 0000000..19d16b1 --- /dev/null +++ b/gdb/testsuite/gdb.ada/dyn-bit-offset.exp @@ -0,0 +1,46 @@ +# Copyright 2025 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +load_lib "ada.exp" + +require allow_ada_tests + +standard_ada_testfile exam + +set flags {debug} +if {[ada_minimal_encodings]} { + lappend flags additional_flags=-fgnat-encodings=minimal +} + +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable $flags] != ""} { + return -1 +} + +clean_restart ${testfile} + +set bp_location [gdb_get_line_number "STOP" ${testdir}/exam.adb] +runto "exam.adb:$bp_location" + +gdb_test_multiple "print spr" "" { + -re -wrap " = \\(discr => 3, array_field => \\(-5, -6, -7\\), field => -4, another_field => -6\\)" { + pass $gdb_test_name + } + -re -wrap " = \\(discr => 3, array_field => \\(-5, -6, -7\\), field => -4, another_field => -4\\)" { + # A known GCC bug. + xfail $gdb_test_name + } +} + +gdb_test "print spr.field" " = -4" diff --git a/gdb/testsuite/gdb.ada/dyn-bit-offset/exam.adb b/gdb/testsuite/gdb.ada/dyn-bit-offset/exam.adb new file mode 100644 index 0000000..a882afd --- /dev/null +++ b/gdb/testsuite/gdb.ada/dyn-bit-offset/exam.adb @@ -0,0 +1,45 @@ +-- Copyright 2025 Free Software Foundation, Inc. +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. + +procedure Exam is + type Small is range -7 .. -4; + for Small'Size use 2; + + type Packed_Array is array (Integer range <>) of Small; + pragma pack (Packed_Array); + + subtype Range_Int is Natural range 0 .. 7; + + type Some_Packed_Record (Discr : Range_Int := 3) is record + Array_Field : Packed_Array (1 .. Discr); + Field: Small; + case Discr is + when 3 => + Another_Field : Small; + when others => + null; + end case; + end record; + pragma Pack (Some_Packed_Record); + pragma No_Component_Reordering (Some_Packed_Record); + + SPR : Some_Packed_Record := (Discr => 3, + Field => -4, + Another_Field => -6, + Array_Field => (-5, -6, -7)); + +begin + null; -- STOP +end Exam; diff --git a/gdb/testsuite/gdb.ada/fixed_points.exp b/gdb/testsuite/gdb.ada/fixed_points.exp index 8bb9e10..0e65004 100644 --- a/gdb/testsuite/gdb.ada/fixed_points.exp +++ b/gdb/testsuite/gdb.ada/fixed_points.exp @@ -90,6 +90,10 @@ foreach_gnat_encoding scenario flags {all minimal} { # This only started working in GCC 11. if {$scenario == "minimal" && [gnat_version_compare >= 11]} { gdb_test "print fp5_var" " = 3e-19" + + gdb_test "print Float(Object_Fixed) = Float(Semicircle_Delta * 5)" \ + " = true" \ + "examine object_fixed" } # This failed before GCC 10. diff --git a/gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb b/gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb index adab614..94a41b9 100644 --- a/gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb +++ b/gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb @@ -64,6 +64,12 @@ procedure Fixed_Points is for Another_Type'size use 64; Another_Fixed : Another_Type := Another_Delta * 5; + Semicircle_Delta : constant := 1.0/(2**31); + type Semicircle_Type is delta Semicircle_Delta range -1.0 .. (1.0 - Semicircle_Delta); + for Semicircle_Type'small use Semicircle_Delta; + for Semicircle_Type'size use 32; + Object_Fixed : Semicircle_Type := Semicircle_Delta * 5; + begin Base_Object := 1.0/16.0; -- Set breakpoint here Subtype_Object := 1.0/16.0; @@ -75,4 +81,5 @@ begin Do_Nothing (FP4_Var'Address); Do_Nothing (FP5_Var'Address); Do_Nothing (Another_Fixed'Address); + Do_Nothing (Object_Fixed'Address); end Fixed_Points; diff --git a/gdb/testsuite/gdb.ada/packed_record_2.exp b/gdb/testsuite/gdb.ada/packed_record_2.exp new file mode 100644 index 0000000..d0bcdbd --- /dev/null +++ b/gdb/testsuite/gdb.ada/packed_record_2.exp @@ -0,0 +1,61 @@ +# Copyright 2025 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +load_lib "ada.exp" + +require allow_ada_tests + +standard_ada_testfile exam + +set flags {debug} +if {[ada_minimal_encodings]} { + lappend flags additional_flags=-fgnat-encodings=minimal +} + +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable $flags] != ""} { + return -1 +} + +clean_restart ${testfile} + +set bp_location [gdb_get_line_number "STOP" ${testdir}/exam.adb] +runto "exam.adb:$bp_location" + +set spr_contents "discr => 3, field => -4, array_field => \\(-5, -6, -7\\)" + +gdb_test "print spr" " = \\($spr_contents\\)" + +gdb_test "print spr.discr" " = 3" + +# See PR ada/32880 -- gdb should probably print array (1 .. 3) here, +# but instead shows array (<>). However as this isn't totally +# relevant to this test, we just accept it. +gdb_test "ptype spr" \ + [multi_line \ + "type = tagged record" \ + " discr: range 1 .. 8;" \ + " field: range -7 .. -4;" \ + " array_field: array \\(<>\\) of exam.small <packed: 2-bit elements>;" \ + "end record"] + +gdb_test_multiple "print sc" "" { + -re " \\($spr_contents, outer => 2, another_array => \\(-7, -6\\)\\)" { + pass $gdb_test_name + } + -re " \\($spr_contents, outer => $decimal, another_array => \\(.*\\)\\)" { + # Other output is a known GCC bug. + xfail $gdb_test_name + } +} diff --git a/gdb/testsuite/gdb.ada/packed_record_2/exam.adb b/gdb/testsuite/gdb.ada/packed_record_2/exam.adb new file mode 100644 index 0000000..e528ecf --- /dev/null +++ b/gdb/testsuite/gdb.ada/packed_record_2/exam.adb @@ -0,0 +1,51 @@ +-- Copyright 2025 Free Software Foundation, Inc. +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. + +procedure Exam is + type Small is range -7 .. -4; + for Small'Size use 2; + + type Range_Int is range 1 .. 8; + for Range_Int'Size use 3; + + type Packed_Array is array (Range_Int range <>) of Small; + pragma pack (Packed_Array); + + type Some_Packed_Record (Discr : Range_Int) is tagged record + Field: Small; + Array_Field : Packed_Array (1 .. Discr); + end record; + pragma Pack (Some_Packed_Record); + + type Sub_Class (Inner, Outer : Range_Int) + is new Some_Packed_Record (Inner) with + record + Another_Array : Packed_Array (1 .. Outer); + end record; + pragma Pack (Sub_Class); + + SPR : Some_Packed_Record := (Discr => 3, + Field => -4, + Array_Field => (-5, -6, -7)); + + SC : Sub_Class := (Inner => 3, + Outer => 2, + Field => -4, + Array_Field => (-5, -6, -7), + Another_Array => (-7, -6)); + +begin + null; -- STOP +end Exam; diff --git a/gdb/testsuite/gdb.ada/task_switch_in_core.exp b/gdb/testsuite/gdb.ada/task_switch_in_core.exp index 3aafc2b..bded377 100644 --- a/gdb/testsuite/gdb.ada/task_switch_in_core.exp +++ b/gdb/testsuite/gdb.ada/task_switch_in_core.exp @@ -15,7 +15,7 @@ load_lib "ada.exp" -require allow_ada_tests +require allow_ada_tests gcore_cmd_available standard_ada_testfile crash diff --git a/gdb/testsuite/gdb.base/coredump-filter-build-id.exp b/gdb/testsuite/gdb.base/coredump-filter-build-id.exp index 7594cc2..eb5b489 100644 --- a/gdb/testsuite/gdb.base/coredump-filter-build-id.exp +++ b/gdb/testsuite/gdb.base/coredump-filter-build-id.exp @@ -28,7 +28,7 @@ if { ![istarget *-*-linux*] } { untested "$testfile.exp" return -1 } -require is_x86_64_m64_target +require is_x86_64_m64_target gcore_cmd_available if { [prepare_for_testing "failed to prepare" $testfile $srcfile {debug build-id}] } { return -1 diff --git a/gdb/testsuite/gdb.base/gcore.exp b/gdb/testsuite/gdb.base/gcore.exp index 5251e3f..0a9f099 100644 --- a/gdb/testsuite/gdb.base/gcore.exp +++ b/gdb/testsuite/gdb.base/gcore.exp @@ -16,6 +16,7 @@ # This file was written by Michael Snyder (msnyder@redhat.com) # This is a test for the gdb command "generate-core-file". +require gcore_cmd_available standard_testfile diff --git a/gdb/testsuite/gdb.base/print-symbol-loading.exp b/gdb/testsuite/gdb.base/print-symbol-loading.exp index 15f2c19..c9e2480 100644 --- a/gdb/testsuite/gdb.base/print-symbol-loading.exp +++ b/gdb/testsuite/gdb.base/print-symbol-loading.exp @@ -15,7 +15,7 @@ # Test the "print symbol-loading" option. -require allow_shlib_tests +require allow_shlib_tests gcore_cmd_available standard_testfile print-symbol-loading-main.c set libfile print-symbol-loading-lib diff --git a/gdb/testsuite/gdb.base/solib-search.exp b/gdb/testsuite/gdb.base/solib-search.exp index 2efad18..35b0314 100644 --- a/gdb/testsuite/gdb.base/solib-search.exp +++ b/gdb/testsuite/gdb.base/solib-search.exp @@ -16,7 +16,7 @@ # Test solib-search-path, and in the case of solib-svr4.c whether l_addr_p # is properly reset when the path is changed. -require allow_shlib_tests +require allow_shlib_tests gcore_cmd_available require {!is_remote target} # Build "wrong" and "right" versions of the libraries in separate directories. diff --git a/gdb/testsuite/gdb.cp/templates.exp b/gdb/testsuite/gdb.cp/templates.exp index 74e4a92..52d0229 100644 --- a/gdb/testsuite/gdb.cp/templates.exp +++ b/gdb/testsuite/gdb.cp/templates.exp @@ -58,9 +58,9 @@ proc test_ptype_of_templates {} { xfail "ptype T5<int> (obsolescent gcc or gdb)" } -re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}void T5\\(int\\);${ws}void T5\\((T5<int> const|const T5<int>) ?&\\);${ws}~T5\\(\\);${ws}static void \\* operator new\\((size_t|unsigned( int| long|))\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\}\r\n$gdb_prompt $" { - # This also triggers gdb/1113... - kfail "gdb/1111" "ptype T5<int>" - # Add here a PASS case when PR gdb/1111 gets fixed. + # This also triggers gdb/8218... + kfail "gdb/8216" "ptype T5<int>" + # Add here a PASS case when PR gdb/8216 gets fixed. # These are really: # http://sourceware.org/bugzilla/show_bug.cgi?id=8216 # http://sourceware.org/bugzilla/show_bug.cgi?id=8218 @@ -98,9 +98,9 @@ proc test_ptype_of_templates {} { xfail "ptype t5i (obsolescent gcc or gdb) -- without size_t" } -re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}void T5\\(int\\);${ws}void T5\\((T5<int> const|const T5<int>) ?&\\);${ws}~T5\\(\\);${ws}static void \\* operator new\\((size_t|unsigned( int| long|))\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\}\r\n$gdb_prompt $" { - # This also triggers gdb/1113... - kfail "gdb/1111" "ptype t5i" - # Add here a PASS case when PR gdb/1111 gets fixed. + # This also triggers gdb/8218... + kfail "gdb/8216" "ptype t5i" + # Add here a PASS case when PR gdb/8216 gets fixed. # These are really: # http://sourceware.org/bugzilla/show_bug.cgi?id=8216 # http://sourceware.org/bugzilla/show_bug.cgi?id=8218 @@ -132,7 +132,7 @@ proc test_template_breakpoints {} { "constructor breakpoint" } -re "0. cancel.*\[\r\n\]*.1. all.*\[\r\n\]*.2. T5 at .*\[\r\n\]*.3. T5 at .*\[\r\n\]*> $" { - setup_kfail "gdb/1062" "*-*-*" + setup_kfail "gdb/8167" "*-*-*" gdb_test "0" \ "nonsense intended to insure that this test fails" \ "constructor breakpoint" @@ -151,7 +151,7 @@ proc test_template_breakpoints {} { } -re "the class `T5<int>' does not have destructor defined\r\nHint: try 'T5<int>::~T5<TAB> or 'T5<int>::~T5<ESC-\\?>\r\n\\(Note leading single quote.\\)\r\n$gdb_prompt $" { - kfail "gdb/1112" "destructor breakpoint" + kfail "gdb/8217" "destructor breakpoint" } } @@ -307,7 +307,7 @@ gdb_test_multiple "ptype/r Foo" "ptype Foo" { } -re "type = class Foo<int> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int foo\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" { # GCC 3.1, DWARF-2 output. - kfail "gdb/57" "ptype Foo" + kfail "gdb/7162" "ptype Foo" } -re "No symbol \"Foo\" in current context.\r\n$gdb_prompt $" { # GCC 2.95.3, stabs+ output. @@ -342,28 +342,25 @@ gdb_test_multiple "ptype/r fchar" "ptype fchar" { # ptype Foo<volatile char *> gdb_test_multiple "ptype/r fvpchar" "ptype fvpchar" { - -re "type = (class |)Foo<volatile char ?\\*> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*.*char.*\\*t;\r\n\r\n\[ \t\]*.*char \\* foo\\(int,.*char.*\\*\\);\r\n\\}\r\n$gdb_prompt $" { - pass "ptype fvpchar" - } - -re "type = (class |)Foo<volatile char ?\\*> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*.*char.*\\*t;\r\n\r\n\[ \t\]*.*char \\* foo\\(int,.*char.*\\*\\);.*\r\n\\}\r\n$gdb_prompt $" { + -re "type = class Foo<char volatile\\*> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*volatile char \\*t;\r\n\r\n\[ \t\]*volatile char \\* foo\\(int, volatile char \\*\\);.*\r\n\\}\r\n$gdb_prompt $" { pass "ptype fvpchar" } -re "type = (class |)Foo<char volatile ?\\*> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*.*char.*\\*t;\r\n\r\n\[ \t\]*.*char \\* foo\\(int,.*char.*\\*\\);\r\n\\}\r\n$gdb_prompt $" { - kfail "gdb/1512" "ptype fvpchar" + kfail "gdb/8617" "ptype fvpchar" } } # print a function from Foo<volatile char *> # This test is sensitive to whitespace matching, so we'll do it twice, -# varying the spacing, because of PR gdb/33. +# varying the spacing, because of PR gdb/7138. gdb_test_multiple "print Foo<volatile char *>::foo" "print Foo<volatile char *>::foo" { -re "\\$\[0-9\]* = \\{.*char \\*\\((class |)Foo<(volatile char|char volatile) ?\\*> \\*(| const), int, .*char \\*\\)\\} $hex <Foo<.*char.*\\*>::foo\\(int, .*char.*\\*\\)>\r\n$gdb_prompt $" { pass "print Foo<volatile char *>::foo" } -re "No symbol \"Foo<volatile char \\*>\" in current context.\r\n$gdb_prompt $" { - # This used to be a kfail gdb/33 and then kfail gdb/931. + # This used to be a kfail gdb/7138 and then kfail gdb/8036. fail "print Foo<volatile char *>::foo" } } @@ -373,7 +370,7 @@ gdb_test_multiple "print Foo<volatile char*>::foo" "print Foo<volatile char*>::f pass "print Foo<volatile char*>::foo" } -re "No symbol \"Foo<volatile char\\*>\" in current context.\r\n$gdb_prompt $" { - # This used to be a kfail gdb/33 and then kfail gdb/931. + # This used to be a kfail gdb/7138 and then kfail gdb/8036. fail "print Foo<volatile char*>::foo" } } @@ -390,7 +387,7 @@ gdb_test_multiple "ptype/r Bar" "ptype Bar" { } -re "ptype Bar\r\ntype = class Bar<int, ?33> {\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int bar\\(int, int\\);\r\n}\r\n$gdb_prompt $" { # GCC 3.1, DWARF-2 output. - kfail "gdb/57" "ptype Bar" + kfail "gdb/7162" "ptype Bar" } -re "No symbol \"Bar\" in current context.\r\n$gdb_prompt $" { # GCC 2.95.3, stabs+ output. @@ -433,11 +430,11 @@ gdb_test_multiple "ptype/r Baz" "ptype Baz" { } -re "type = class Baz<int, ?'s'> {\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int baz\\(int, int\\);\r\n}\r\n$gdb_prompt $" { # GCC 3.1, DWARF-2 output. - kfail "gdb/57" "ptype Baz" + kfail "gdb/7162" "ptype Baz" } -re "type = class Baz<int, ?(\\(char\\))?115> {\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int baz\\(int, int\\);\r\n}\r\n$gdb_prompt $" { - # GCC 3.x, DWARF-2 output, running into gdb/57 and gdb/1512. - kfail "gdb/57" "ptype Baz" + # GCC 3.x, DWARF-2 output, running into gdb/7162 and gdb/8617. + kfail "gdb/7162" "ptype Baz" } -re "No symbol \"Baz\" in current context.\r\n$gdb_prompt $" { # GCC 2.95.3, stabs+ output. @@ -479,11 +476,11 @@ gdb_test_multiple "ptype/r Qux" "ptype Qux" { } -re "type = class Qux<char, ?&string> {\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*char t;\r\n\r\n\[ \t\]*char qux\\(int, char\\);\r\n}\r\n$gdb_prompt $" { # GCC 3.1, DWARF-2 output. - kfail "gdb/57" "ptype Qux" + kfail "gdb/7162" "ptype Qux" } -re "type = class Qux<char, ?&\\(string\\)> {\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*char t;\r\n\r\n\[ \t\]*char qux\\(int, char\\);\r\n}\r\n$gdb_prompt $" { - # GCC 3.x, DWARF-2 output; gdb/57 + gdb/1512. - kfail "gdb/57" "ptype Qux" + # GCC 3.x, DWARF-2 output; gdb/7162 + gdb/8617. + kfail "gdb/7162" "ptype Qux" } -re "No symbol \"Qux\" in current context.\r\n$gdb_prompt $" { # GCC 2.95.3, stabs+ output. @@ -507,7 +504,7 @@ gdb_test_multiple "ptype/r quxint" "ptype quxint" { pass "ptype quxint" } -re "type = class Qux<int, ?& ?\\(string\\)> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int qux\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" { - kfail "gdb/1512" "ptype quxint" + kfail "gdb/8617" "ptype quxint" } } @@ -524,7 +521,7 @@ gdb_test_multiple "ptype/r Spec" "ptype Spec" { } -re "type = class Spec<int, ?char> {\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\r\n\[ \t\]*int spec\\(char\\);\r\n}\r\n$gdb_prompt $" { # GCC 3.1, DWARF-2 output. - kfail "gdb/57" "ptype Spec" + kfail "gdb/7162" "ptype Spec" } -re "No symbol \"Spec\" in current context.\r\n$gdb_prompt $" { # GCC 2.95.3, stabs+ output. diff --git a/gdb/testsuite/gdb.guile/scm-color.exp b/gdb/testsuite/gdb.guile/scm-color.exp index bbc9e71..578f712 100644 --- a/gdb/testsuite/gdb.guile/scm-color.exp +++ b/gdb/testsuite/gdb.guile/scm-color.exp @@ -20,7 +20,10 @@ load_lib gdb-guile.exp require allow_guile_tests -clean_restart +# Start GDB with styling support. +with_ansi_styling_terminal { + clean_restart +} gdb_install_guile_utils gdb_install_guile_module @@ -108,3 +111,8 @@ gdb_test [concat "guile " \ "\033\\\[31m\033\\\[42mred on green\033\\\[49m red on default\033\\\[39m" \ "escape sequences" +# Ensure that turning styling off means no escape sequences. +gdb_test_no_output "set style enabled off" +gdb_test_no_output "guile (display (color-escape-sequence c_red #t))" +gdb_test_no_output "guile (display (color-escape-sequence c_red #f))" +gdb_test_no_output "set style enabled on" diff --git a/gdb/testsuite/gdb.python/py-color.exp b/gdb/testsuite/gdb.python/py-color.exp index 3563d22..2601cf3 100644 --- a/gdb/testsuite/gdb.python/py-color.exp +++ b/gdb/testsuite/gdb.python/py-color.exp @@ -19,8 +19,10 @@ load_lib gdb-python.exp require allow_python_tests -# Start with a fresh gdb. -clean_restart +# Start with a fresh GDB, but enable color support. +with_ansi_styling_terminal { + clean_restart +} gdb_test_no_output "python get_color_attrs = lambda c: \"%s %s %s %s %s\" % (str(c), c.colorspace, c.is_none, c.is_indexed, c.is_direct)" \ "get_color_attrs helper" @@ -115,6 +117,12 @@ gdb_test [concat "python print (c_red.escape_sequence (is_foreground = True) + " "\033\\\[31m\033\\\[42mred on green\033\\\[49m red on default\033\\\[39m" \ "escape sequences using keyword arguments" +# Ensure that turning styling off means no escape sequences. +gdb_test_no_output "set style enabled off" +gdb_test_no_output "python print (c_red.escape_sequence (True), end='')" +gdb_test_no_output "python print (c_red.escape_sequence (False), end='')" +gdb_test_no_output "set style enabled on" + gdb_test_multiline "Try to sub-class gdb.Color" \ "python" "" \ "class my_color(gdb.Color):" "" \ diff --git a/gdb/testsuite/gdb.rocm/mi-attach.exp b/gdb/testsuite/gdb.rocm/mi-attach.exp index 2ca610c..37ce92a 100644 --- a/gdb/testsuite/gdb.rocm/mi-attach.exp +++ b/gdb/testsuite/gdb.rocm/mi-attach.exp @@ -13,10 +13,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +load_lib rocm.exp load_lib mi-support.exp set MIFLAGS "-i=mi" -require can_spawn_for_attach +require can_spawn_for_attach allow_hipcc_tests standard_testfile .cpp diff --git a/gdb/testsuite/gdb.tui/corefile-run.exp b/gdb/testsuite/gdb.tui/corefile-run.exp index 89a48b5..657fc83 100644 --- a/gdb/testsuite/gdb.tui/corefile-run.exp +++ b/gdb/testsuite/gdb.tui/corefile-run.exp @@ -18,6 +18,8 @@ # # Ref.: https://bugzilla.redhat.com/show_bug.cgi?id=1765117 +require gcore_cmd_available + tuiterm_env standard_testfile tui-layout.c diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index ead14bd..2a5d37c 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -7007,6 +7007,24 @@ proc gdb_load_cmd { args } { return -1 } +# Return non-zero if 'gcore' command is available. +gdb_caching_proc gcore_cmd_available { } { + gdb_exit + gdb_start + + # Does this gdb support gcore? + gdb_test_multiple "help gcore" "" { + -re -wrap "Undefined command: .*" { + return 0 + } + -re -wrap "Save a core file .*" { + return 1 + } + } + + return 0 +} + # Invoke "gcore". CORE is the name of the core file to write. TEST # is the name of the test case. This will return 1 if the core file # was created, 0 otherwise. If this fails to make a core file because diff --git a/gdb/value.c b/gdb/value.c index 0f1be2e..41dce77 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -3266,6 +3266,9 @@ unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr, } } + if (field_type->code () == TYPE_CODE_RANGE) + val += field_type->bounds ()->bias; + return val; } @@ -3296,21 +3299,28 @@ unpack_value_field_as_long (struct type *type, const gdb_byte *valaddr, return 1; } -/* Unpack a field FIELDNO of the specified TYPE, from the anonymous - object at VALADDR. See unpack_bits_as_long for more details. */ +/* See value.h. */ LONGEST -unpack_field_as_long (struct type *type, const gdb_byte *valaddr, int fieldno) +unpack_field_as_long (const gdb_byte *valaddr, struct field *field) { - int bitpos = type->field (fieldno).loc_bitpos (); - int bitsize = type->field (fieldno).bitsize (); - struct type *field_type = type->field (fieldno).type (); + int bitpos = field->loc_bitpos (); + int bitsize = field->bitsize (); + struct type *field_type = field->type (); return unpack_bits_as_long (field_type, valaddr, bitpos, bitsize); } /* See value.h. */ +LONGEST +unpack_field_as_long (struct type *type, const gdb_byte *valaddr, int fieldno) +{ + return unpack_field_as_long (valaddr, &type->field (fieldno)); +} + +/* See value.h. */ + void value::unpack_bitfield (struct value *dest_val, LONGEST bitpos, LONGEST bitsize, diff --git a/gdb/value.h b/gdb/value.h index 71d0ba1..0c7c785 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -1058,10 +1058,19 @@ extern gdb_mpz value_as_mpz (struct value *val); extern LONGEST unpack_long (struct type *type, const gdb_byte *valaddr); extern CORE_ADDR unpack_pointer (struct type *type, const gdb_byte *valaddr); +/* Unpack a field FIELDNO of the specified TYPE, from the anonymous + object at VALADDR. See unpack_bits_as_long for more details. */ + extern LONGEST unpack_field_as_long (struct type *type, const gdb_byte *valaddr, int fieldno); +/* Unpack a field, FIELD, from the anonymous object at VALADDR. See + unpack_bits_as_long for more details. */ + +extern LONGEST unpack_field_as_long (const gdb_byte *valaddr, + struct field *field); + /* Unpack a bitfield of the specified FIELD_TYPE, from the object at VALADDR, and store the result in *RESULT. The bitfield starts at BITPOS bits and contains BITSIZE bits; if diff --git a/gprofng/common/gp-experiment.h b/gprofng/common/gp-experiment.h index fab08f1..7abccdf 100644 --- a/gprofng/common/gp-experiment.h +++ b/gprofng/common/gp-experiment.h @@ -39,6 +39,23 @@ #define IS_DESC_EXPT(exptname) (strstr(exptname,DESCENDANT_EXPT_KEY) != NULL) #define IS_FNDR_EXPT(exptname) (strstr(exptname,DESCENDANT_EXPT_KEY) == NULL) +// environment variables that must be forwarded to libcollector +#define SP_COLLECTOR_PARAMS "SP_COLLECTOR_PARAMS" +#define SP_COLLECTOR_EXPNAME "SP_COLLECTOR_EXPNAME" +#define SP_COLLECTOR_FOLLOW_SPEC "SP_COLLECTOR_FOLLOW_SPEC" +#define SP_COLLECTOR_FOUNDER "SP_COLLECTOR_FOUNDER" +#define SP_PRELOAD_STRINGS "SP_COLLECTOR_PRELOAD" +#define LD_PRELOAD_STRINGS "LD_PRELOAD" +#define SP_LIBPATH_STRINGS "SP_COLLECTOR_LIBRARY_PATH" +#define LD_LIBPATH_STRINGS "LD_LIBRARY_PATH" +#define JAVA_TOOL_OPTIONS "JAVA_TOOL_OPTIONS" +#define COLLECTOR_JVMTI_OPTION "-agentlib:gp-collector" +#define LIBGP_COLLECTOR "libgp-collector.so" +#define GPROFNG_PRELOAD_LIBDIRS "GPROFNG_PRELOAD_LIBDIRS" +#define SP_COLLECTOR_ORIGIN_COLLECT "SP_COLLECTOR_ORIGIN_COLLECT" +#define SP_COLLECTOR_DEBUG "SP_COLLECTOR_DEBUG" +#define SP_COLLECTOR_TRACELEVEL "SP_COLLECTOR_TRACELEVEL" + /* File name definitions */ #define SP_ARCHIVES_DIR "archives" #define SP_ARCHIVE_LOG_FILE "archive.log" @@ -86,70 +103,31 @@ /* records for log and loadobjects files */ /* note that these are in alphabetical order */ -#define SP_JCMD_ARCH "architecture" #define SP_JCMD_ARCHIVE "archive_run" -#define SP_JCMD_ARGLIST "arglist" #define SP_JCMD_BLKSZ "blksz" #define SP_JCMD_CERROR "cerror" -#define SP_JCMD_CLASS_LOAD "class_load" -#define SP_JCMD_CLASS_UNLOAD "class_unload" #define SP_JCMD_COLLENV "collenv" #define SP_JCMD_COMMENT "comment" -#define SP_JCMD_CPUID "cpuid" #define SP_JCMD_CWARN "cwarn" -#define SP_JCMD_CWD "cwd" -#define SP_JCMD_CVERSION "cversion" -#define SP_JCMD_DATARACE "datarace" -#define SP_JCMD_DEADLOCK "deadlock" #define SP_JCMD_DELAYSTART "delay_start" #define SP_JCMD_DESC_START "desc_start" #define SP_JCMD_DESC_STARTED "desc_started" -#define SP_JCMD_DVERSION "dversion" #define SP_JCMD_EXEC_START "exec_start" #define SP_JCMD_EXEC_ERROR "exec_error" #define SP_JCMD_EXIT "exit" -#define SP_JCMD_EXPT_DURATION "exp_duration" #define SP_JCMD_FAKETIME "faketime" -#define SP_JCMD_FN_LOAD "fn_load" -#define SP_JCMD_FN_UNLOAD "fn_unload" -#define SP_JCMD_FUN_MAP "fun_map" -#define SP_JCMD_FUN_UNMAP "fun_unmap" #define SP_JCMD_HEAPTRACE "heaptrace" -#define SP_JCMD_HOSTNAME "hostname" #define SP_JCMD_HWC_DEFAULT "hwc_default" #define SP_JCMD_HW_COUNTER "hwcounter" -#define SP_JCMD_HW_SIM_CTR "hwsimctr" #define SP_JCMD_IOTRACE "iotrace" -#define SP_JCMD_JCM_LOAD "jcm_load" -#define SP_JCMD_JCM_UNLOAD "jcm_unload" -#define SP_JCMD_JCM_MAP "jcm_map" -#define SP_JCMD_JCM_UNMAP "jcm_unmap" #define SP_JCMD_JTHREND "jthread_end" #define SP_JCMD_JTHRSTART "jthread_start" #define SP_JCMD_GCEND "gc_end" #define SP_JCMD_GCSTART "gc_start" #define SP_JCMD_JVERSION "jversion" -//#define SP_JCMD_KPROFILE "kprofile" /* TBR */ #define SP_JCMD_LIMIT "limit" #define SP_JCMD_LINETRACE "linetrace" -#define SP_JCMD_LO_OPEN "lo_open" -#define SP_JCMD_LO_CLOSE "lo_close" -#define SP_JCMD_MOD_OPEN "mod_open" -#define SP_JCMD_MPIEXP "MPIexperiment" -#define SP_JCMD_MPI_NO_TRACE "MPI_no_trace" -#define SP_JCMD_MPIOMPVER "mpi_openmpi_version" -#define SP_JCMD_MPITRACEVER "mpi_trace_version" -#define SP_JCMD_MPIPP "mpipp" -#define SP_JCMD_MPIPPERR "mpipp_err" -#define SP_JCMD_MPIPPWARN "mpipp_warn" -#define SP_JCMD_MPISTATE "mpistate" -#define SP_JCMD_MPITRACE "mpitrace" /* backwards compat only */ -#define SP_JCMD_MPVIEW "mpview" -#define SP_JCMD_MSGTRACE "msgtrace" #define SP_JCMD_NOIDLE "noidle" -#define SP_JCMD_OMPTRACE "omptrace" -#define SP_JCMD_OS "os" -#define SP_JCMD_PAGESIZE "pagesize" #define SP_JCMD_PAUSE "pause" #define SP_JCMD_PAUSE_SIG "pause_signal" #define SP_JCMD_PROFILE "profile" @@ -158,21 +136,15 @@ #define SP_JCMD_SAMPLE "sample" #define SP_JCMD_SAMPLE_PERIOD "sample_period" #define SP_JCMD_SAMPLE_SIG "sample_signal" -#define SP_JCMD_SEGMENT_MAP "seg_map" -#define SP_JCMD_SEGMENT_UNMAP "seg_unmap" #define SP_JCMD_SRCHPATH "search_path" #define SP_JCMD_STACKBASE "stackbase" -#define SP_JCMD_SUNPERF "sunperf" #define SP_JCMD_SYNCTRACE "synctrace" #define SP_JCMD_TERMINATE "terminate" #define SP_JCMD_THREAD_PAUSE "thread_pause" #define SP_JCMD_THREAD_RESUME "thread_resume" -#define SP_JCMD_USERNAME "username" #define SP_JCMD_VERSION "version" -#define SP_JCMD_WSIZE "wsize" /* strings naming memory-segments */ -#define SP_MAP_ANON "Anon" #define SP_MAP_HEAP "Heap" #define SP_MAP_STACK "Stack" #define SP_MAP_SHMEM "SHMid" diff --git a/gprofng/libcollector/collector.c b/gprofng/libcollector/collector.c index 8d978a6..c5fa3cb 100644 --- a/gprofng/libcollector/collector.c +++ b/gprofng/libcollector/collector.c @@ -182,11 +182,12 @@ static void init_tracelevel () { #if DEBUG - char *s = CALL_UTIL (getenv)("SP_COLLECTOR_TRACELEVEL"); + char *s = CALL_UTIL (getenv)(SP_COLLECTOR_TRACELEVEL); if (s != NULL) __collector_tracelevel = CALL_UTIL (atoi)(s); - TprintfT (DBG_LT0, "collector: SP_COLLECTOR_TRACELEVEL=%d\n", __collector_tracelevel); - s = CALL_UTIL (getenv)("SP_COLLECTOR_DEBUG"); + TprintfT (DBG_LT0, "collector: %s=%d\n", SP_COLLECTOR_TRACELEVEL, + __collector_tracelevel); + s = CALL_UTIL (getenv)(SP_COLLECTOR_DEBUG); if (s != NULL) collector_debug_opt = CALL_UTIL (atoi)(s) & ~(SP_DUMP_TIME | SP_DUMP_FLAG); #endif @@ -239,21 +240,24 @@ collector_init () collector_module_init (get_collector_interface ()); /* determine experiment name */ - char *exp = CALL_UTIL (getenv)("SP_COLLECTOR_EXPNAME"); + char *exp = CALL_UTIL (getenv)(SP_COLLECTOR_EXPNAME); if ((exp == NULL) || (CALL_UTIL (strlen)(exp) == 0)) { - TprintfT (DBG_LT0, "collector_init: SP_COLLECTOR_EXPNAME undefined - no experiment to start\n"); + TprintfT (DBG_LT0, "collector_init: %s undefined. no experiment to start\n", + SP_COLLECTOR_EXPNAME); /* not set -- no experiment to run */ return; } else - TprintfT (DBG_LT1, "collector_init: found SP_COLLECTOR_EXPNAME = %s\n", exp); + TprintfT (DBG_LT1, "collector_init: found %s = %s\n", + SP_COLLECTOR_EXPNAME, exp); /* determine the data descriptor for the experiment */ - char *params = CALL_UTIL (getenv)("SP_COLLECTOR_PARAMS"); + char *params = CALL_UTIL (getenv)(SP_COLLECTOR_PARAMS); if (params == NULL) { - TprintfT (0, "collector_init: SP_COLLECTOR_PARAMS undefined - no experiment to start\n"); + TprintfT (0, "collector_init: %s undefined - no experiment to start\n", + SP_COLLECTOR_EXPNAME); return; } @@ -494,7 +498,8 @@ __collector_open_experiment (const char *exp, const char *params, sp_origin_t or return COL_ERROR_EXPOPEN; } __collector_start_time = collector_interface.getHiResTime (); - TprintfT (DBG_LT1, "\n\t\t__collector_open_experiment(SP_COLLECTOR_EXPNAME=%s, params=%s, origin=%d); setting start_time\n", + TprintfT (DBG_LT1, "\n\t\t__collector_open_experiment(%s=%s, params=%s, " + "origin=%d); setting start_time\n", SP_COLLECTOR_EXPNAME, exp, params, origin); if (environ) __collector_env_printall ("__collector_open_experiment", environ); @@ -548,23 +553,20 @@ __collector_open_experiment (const char *exp, const char *params, sp_origin_t or is_founder = getpid (); if (origin != SP_ORIGIN_DBX_ATTACH) { - envar = CALL_UTIL (getenv)("SP_COLLECTOR_FOUNDER"); + envar = CALL_UTIL (getenv)(SP_COLLECTOR_FOUNDER); if (envar) is_founder = CALL_UTIL (atoi)(envar); if (is_founder != 0) { if (is_founder != getpid ()) { - TprintfT (0, "__collector_open_experiment SP_COLLECTOR_FOUNDER=%d != pid(%d)\n", - is_founder, getpid ()); - //CALL_UTIL(fprintf)(stderr, "__collector_open_experiment SP_COLLECTOR_FOUNDER=%d != pid(%d); not recording experiment\n", - //is_founder, getpid() ); - //return COL_ERROR_UNEXP_FOUNDER; + TprintfT (0, "__collector_open_experiment %s=%d != pid(%d)\n", + SP_COLLECTOR_FOUNDER, is_founder, getpid ()); is_founder = 0; // Special case (CR 22917352) } /* clear FOUNDER for descendant experiments */ - TprintfT (0, "__collector_open_experiment setting SP_COLLECTOR_FOUNDER=0\n"); - CALL_UTIL (strlcpy)(buffer, "SP_COLLECTOR_FOUNDER=0", sizeof (buffer)); + TprintfT (0, "__collector_open_experiment setting %s=0\n", SP_COLLECTOR_FOUNDER); + CALL_UTIL (snprintf)(buffer, sizeof (buffer), "%s=0", SP_COLLECTOR_FOUNDER); CALL_UTIL (putenv)(buffer); } } @@ -617,8 +619,10 @@ __collector_open_experiment (const char *exp, const char *params, sp_origin_t or return COL_ERROR_BADDIR; } static char exp_name_env[MAXPATHLEN + 1]; - TprintfT (DBG_LT1, "collector_open_experiment: setting SP_COLLECTOR_EXPNAME to %s\n", __collector_exp_dir_name); - CALL_UTIL (snprintf)(exp_name_env, sizeof (exp_name_env), "SP_COLLECTOR_EXPNAME=%s", __collector_exp_dir_name); + TprintfT (DBG_LT1, "collector_open_experiment: setting %s to %s\n", + SP_COLLECTOR_EXPNAME, __collector_exp_dir_name); + CALL_UTIL (snprintf)(exp_name_env, sizeof (exp_name_env), "%s=%s", + SP_COLLECTOR_EXPNAME, __collector_exp_dir_name); CALL_UTIL (putenv)(exp_name_env); } /* Check that the name is that of a directory (new structure) */ @@ -1049,8 +1053,10 @@ collector_tail_init (const char *parent_exp_name) if (collector_exp_dir_append_x (linenum, parent_exp_name) != 0) return COL_ERROR_BADDIR; static char exp_name_env[MAXPATHLEN + 1]; - CALL_UTIL (snprintf)(exp_name_env, sizeof (exp_name_env), "SP_COLLECTOR_EXPNAME=%s", __collector_exp_dir_name); - TprintfT (DBG_LT1, "collector_tail_init: setting SP_COLLECTOR_EXPNAME to %s\n", __collector_exp_dir_name); + CALL_UTIL (snprintf)(exp_name_env, sizeof (exp_name_env), "%s=%s", + SP_COLLECTOR_EXPNAME, __collector_exp_dir_name); + TprintfT (DBG_LT1, "collector_tail_init: setting %s to %s\n", + SP_COLLECTOR_EXPNAME, __collector_exp_dir_name); CALL_UTIL (putenv)(exp_name_env); } /* initialize the segments map and mmap interposition */ diff --git a/gprofng/libcollector/descendants.h b/gprofng/libcollector/descendants.h index 0148410..7d594b3 100644 --- a/gprofng/libcollector/descendants.h +++ b/gprofng/libcollector/descendants.h @@ -44,7 +44,6 @@ typedef enum LM_TRACK_LINEAGE = 1, /* env vars preserved, recording */ } line_mode_t; -extern line_mode_t line_mode; extern int user_follow_mode; extern int java_mode; extern int dbg_current_mode; /* for debug only */ @@ -56,19 +55,6 @@ extern char **sp_env_backup; #define PUSH_REENTRANCE(x) ((*(x))++) #define POP_REENTRANCE(x) ((*(x))--) -/* environment variables that must be forwarded to descendents */ -#define SP_COLLECTOR_PARAMS "SP_COLLECTOR_PARAMS" -#define SP_COLLECTOR_EXPNAME "SP_COLLECTOR_EXPNAME" -#define SP_COLLECTOR_FOLLOW_SPEC "SP_COLLECTOR_FOLLOW_SPEC" -#define SP_COLLECTOR_FOUNDER "SP_COLLECTOR_FOUNDER" -#define SP_PRELOAD_STRINGS "SP_COLLECTOR_PRELOAD" -#define LD_PRELOAD_STRINGS "LD_PRELOAD" -#define SP_LIBPATH_STRINGS "SP_COLLECTOR_LIBRARY_PATH" -#define LD_LIBPATH_STRINGS "LD_LIBRARY_PATH" -#define JAVA_TOOL_OPTIONS "JAVA_TOOL_OPTIONS" -#define COLLECTOR_JVMTI_OPTION "-agentlib:gp-collector" - -extern int __collector_linetrace_shutdown_hwcs_6830763_XXXX; extern void __collector_env_unset (char *envp[]); extern void __collector_env_save_preloads (); extern char ** __collector_env_backup (); diff --git a/gprofng/libcollector/envmgmt.c b/gprofng/libcollector/envmgmt.c index 0c3bea1..0a2add9 100644 --- a/gprofng/libcollector/envmgmt.c +++ b/gprofng/libcollector/envmgmt.c @@ -285,9 +285,6 @@ env_ld_preload_strip (char *envv) for (int v = 0; SP_PRELOAD[v]; v++) if (env_strip (envv, sp_preloads[v])) return 0; - if (line_mode != LM_CLOSED) - TprintfT (DBG_LT2, "env_ld_preload_strip(): WARNING - could not strip SP_PRELOADS from '%s'\n", - envv); return -2; } diff --git a/gprofng/libcollector/linetrace.c b/gprofng/libcollector/linetrace.c index 86d9955..0e3e7cd 100644 --- a/gprofng/libcollector/linetrace.c +++ b/gprofng/libcollector/linetrace.c @@ -37,10 +37,10 @@ #define LT_MAXNAMELEN 1024 #define LT_MAXPATHLEN 1024 -int __collector_linetrace_shutdown_hwcs_6830763_XXXX = 0; +static int __collector_linetrace_shutdown_hwcs_6830763_XXXX = 0; int dbg_current_mode = FOLLOW_NONE; /* for debug only */ unsigned line_key = COLLECTOR_TSD_INVALID_KEY; -line_mode_t line_mode = LM_DORMANT; +static line_mode_t line_mode = LM_DORMANT; int user_follow_mode = FOLLOW_ON; int java_mode = 0; diff --git a/gprofng/src/Dwarf.cc b/gprofng/src/Dwarf.cc index 3b3fd63..23ac5b9 100644 --- a/gprofng/src/Dwarf.cc +++ b/gprofng/src/Dwarf.cc @@ -29,6 +29,7 @@ #include "LoadObject.h" #include "Module.h" #include "DefaultMap.h" +#include "Symbol.h" static int datatypeCmp (const void *a, const void *b) @@ -46,7 +47,6 @@ targetOffsetCmp (const void *a, const void *b) return o1 == o2 ? 0 : (o1 < o2 ? -1 : 1); } - ////////////////////////////////////////////////////////// // class Dwr_type class Dwr_type @@ -441,7 +441,12 @@ DwrCU::get_linkage_name () nm = Dwarf_string (DW_AT_SUN_link_name); if (nm != NULL) return nm; - return Dwarf_string (DW_AT_MIPS_linkage_name); + if (nm != NULL) + return nm; + nm = Dwarf_string (DW_AT_MIPS_linkage_name); + if (nm != NULL) + return nm; + return Dwarf_string (DW_AT_name); } void @@ -490,8 +495,10 @@ DwrCU::parseChild (Dwarf_cnt *ctx) } break; case DW_TAG_subprogram: + { if (dwrTag.get_attr (DW_AT_abstract_origin)) break; + Symbol *sym = NULL; if (dwrTag.get_attr (DW_AT_declaration)) { // Only declaration @@ -499,26 +506,71 @@ DwrCU::parseChild (Dwarf_cnt *ctx) { char *link_name = Dwarf_string (DW_AT_name); if (link_name && streq (link_name, NTXT ("MAIN"))) - ctx->fortranMAIN = Stabs::find_func (NTXT ("MAIN"), ctx->module->functions, true, true); - } - break; + ctx->fortranMAIN = Stabs::find_func (NTXT ("MAIN"), + ctx->module->functions, true, true); + } + sym = Symbol::get_symbol (symbols_sorted_by_name, + get_linkage_name ()); + if (sym == NULL) + break; + func = append_Function (sym, ctx->name); + break; } - func = append_Function (ctx); - if (func) + + Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_specification); + if (dwrAttr) { - if (Stabs::is_fortran (ctx->module->lang_code) && - streq (func->get_match_name (), NTXT ("MAIN"))) - ctx->fortranMAIN = func; - old_name = ctx->name; - Function *old_func = ctx->func; - ctx->name = func->get_match_name (); - ctx->func = func; - parseChild (ctx); - hasChild = 0; - ctx->name = old_name; - ctx->func = old_func; + // Find previous declaration to inherit settings. + sym = find_declaration (dwrAttr->u.offset); + if (sym == NULL) + break; + func = sym->func; + if (func == NULL) + break; + set_source (func); + + Vector <Range *> *ranges = get_ranges (); + if (ranges) + { + Vector<Symbol *> *syms = Symbol::find_symbols (symbols, ranges); + Destroy (ranges); + for (int i = 0, sz = VecSize (syms); i < sz; i++) + { + Symbol *sp = syms->get (i); + if (sp->alias) + sp = sp->alias; + Function *f = sp->func; + if (f == NULL) + f = sp->createFunction (func->module); + f->setLineFirst (func->line_first); + f->setDefSrc (func->def_source); + } + delete (syms); + } + break; } + + sym = Symbol::get_symbol (symbols_sorted_by_name, get_linkage_name ()); + if (sym == NULL) + sym = Symbol::get_symbol (symbols, get_low_pc ()); + if (sym == NULL) + break; + func = append_Function (sym, ctx->name); + if (Stabs::is_fortran (ctx->module->lang_code) && + streq (func->get_match_name (), "MAIN")) + ctx->fortranMAIN = func; + set_source (func); + + old_name = ctx->name; + Function *old_func = ctx->func; + ctx->name = func->get_match_name (); + ctx->func = func; + parseChild (ctx); + hasChild = 0; + ctx->name = old_name; + ctx->func = old_func; break; + } case DW_TAG_module: old_name = ctx->name; ctx->name = Dwarf_string (DW_AT_SUN_link_name); @@ -631,6 +683,21 @@ Dwarf::archive_Dwarf (LoadObject *lo) STR (lo_name), STR (mod->get_name ())); dwrCU->dwrInlinedSubrs->dump (msg); } + for (int i = 0, sz = VecSize (dwrCU->symbols); i < sz; i++) + { + Symbol *sp = dwrCU->symbols->get (i); + Function *f = sp->func; + if (f == NULL) + { + f = sp->createFunction (mod); + if (sp->alias && sp->alias->func) + { + Function *func = sp->alias->func; + f->setLineFirst (func->line_first); + f->setDefSrc (func->def_source); + } + } + } } } return true; @@ -645,6 +712,38 @@ Dwarf::srcline_Dwarf (Module *module) dwrCU->map_dwarf_lines (module); } +static int +rangeCmp (const void *a, const void *b) +{ + Range *item1 = *((Range **) a); + Range *item2 = *((Range **) b); + return item1->low < item2->low ? -1 : (item1->low == item2->low ? 0 : 1); +} + +Vector<Range *> * +Dwarf::get_ranges (uint64_t offset) +{ + if (debug_rangesSec == NULL) + return NULL; + if (offset >= debug_rangesSec->size) + { + Dprintf (DUMP_DWARFLIB, "ERROR: Dwarf::get_ranges(0x%llx). size=0x%llx\n", + (long long) offset, (long long) debug_rangesSec->size); + return NULL; + } + Vector<Range*> *ranges = new Vector<Range*>(); + debug_rangesSec->offset = offset; + for (;;) + { + uint64_t low_pc = debug_rangesSec->GetADDR (); + uint64_t high_pc = debug_rangesSec->GetADDR (); + if (low_pc == 0 || low_pc > high_pc) + break; + ranges->append (new Range (low_pc, high_pc)); + } + ranges->sort (rangeCmp); + return ranges; +} // parse hwcprof info for given module in loadobject @@ -797,11 +896,17 @@ DwrCU::read_hwcprof_info (Dwarf_cnt *ctx) case DW_TAG_subprogram: { Function *old_func = ctx->func; - if (dwrTag.get_attr (DW_AT_abstract_origin) - || dwrTag.get_attr (DW_AT_declaration)) - ctx->func = NULL; - else - ctx->func = append_Function (ctx); + ctx->func = NULL; + if (dwrTag.get_attr (DW_AT_abstract_origin) == NULL + && dwrTag.get_attr (DW_AT_declaration) == NULL) + { + Symbol *sym = Symbol::get_symbol (symbols_sorted_by_name, + get_linkage_name ()); + if (sym == NULL) + sym = Symbol::get_symbol (symbols, get_low_pc ()); + if (sym != NULL) + ctx->func = sym->func; + } read_hwcprof_info (ctx); ctx->func = old_func; break; @@ -955,49 +1060,31 @@ DwrCU::read_hwcprof_info (Dwarf_cnt *ctx) // Append function to module Function * -DwrCU::append_Function (Dwarf_cnt *ctx) +DwrCU::append_Function (Symbol *sym, const char *outerName) { - char *outerName = ctx->name, *name, tmpname[2048]; - Function *func; + if (sym->func != NULL) + return sym->func; + Function *func = sym->createFunction (module); + char *fname = Dwarf_string (DW_AT_name); - if (fname && outerName && !strchr (fname, '.')) + if (fname) { - size_t outerlen = strlen (outerName); - if (outerlen > 0 && outerName[outerlen - 1] == '_') + if (outerName && !strchr (fname, '.')) { - outerlen--; - snprintf (tmpname, sizeof (tmpname), NTXT ("%s"), outerName); - snprintf (tmpname + outerlen, sizeof (tmpname) - outerlen, NTXT (".%s_"), fname); + char *tmpname; + int outerlen = (int) strlen (outerName); + if (outerlen > 0 && outerName[outerlen - 1] == '_') + tmpname = dbe_sprintf ("%.*s.%s_", outerlen - 1, outerName, fname); + else + tmpname = dbe_sprintf ("%s.%s", outerName, fname); + func->set_match_name (tmpname); + Dprintf (DUMP_DWARFLIB, "Generated innerfunc name %s\n", tmpname); + free(tmpname); } else - snprintf (tmpname, sizeof (tmpname), NTXT ("%s.%s"), outerName, fname); - name = tmpname; - Dprintf (DUMP_DWARFLIB, NTXT ("Generated innerfunc name %s\n"), name); - } - else - name = fname; - - char *link_name = get_linkage_name (); - if (link_name == NULL) - link_name = name; - - uint64_t pc = get_low_pc (); - func = dwarf->stabs->append_Function (module, link_name, pc); - if (func != NULL) - { - int lineno = (int) Dwarf_data (DW_AT_decl_line); - func->set_match_name (name); - if (lineno > 0) - { - func->setLineFirst (lineno); - int fileno = ((int) Dwarf_data (DW_AT_decl_file)); - SourceFile *sf = ((fileno >= 0) && (fileno < VecSize (srcFiles))) ? srcFiles->get (fileno) - : module->getMainSrc (); - func->setDefSrc (sf); - func->pushSrcFile (func->def_source, 0); - func->popSrcFile (); - } + func->set_match_name (fname); } + set_source (func); return func; } diff --git a/gprofng/src/Dwarf.h b/gprofng/src/Dwarf.h index 8e3ee7a..f46ad3f 100644 --- a/gprofng/src/Dwarf.h +++ b/gprofng/src/Dwarf.h @@ -60,6 +60,7 @@ class LoadObject; class Module; class DwrCU; class DwrSec; +class Range; class Dwarf { @@ -69,6 +70,7 @@ public: bool archive_Dwarf (LoadObject *lo); void srcline_Dwarf (Module *module); void read_hwcprof_info (Module *module); + Vector<Range *> *get_ranges (uint64_t offset); Stabs::Stab_status status; Vector<DwrCU *> *dwrCUs; diff --git a/gprofng/src/DwarfLib.cc b/gprofng/src/DwarfLib.cc index 3594c2f..9f55ab3 100644 --- a/gprofng/src/DwarfLib.cc +++ b/gprofng/src/DwarfLib.cc @@ -27,9 +27,9 @@ #include "Elf.h" #include "Function.h" #include "Module.h" -#include "StringBuilder.h" #include "DbeArray.h" #include "DbeSession.h" +#include "Symbol.h" #define NO_STMT_LIST ((uint64_t) -1) #define CASE_S(x) case x: s = (char *) #x; break @@ -1795,6 +1795,8 @@ DwrLineRegs::getPath (int fn) DwrCU::DwrCU (Dwarf *_dwarf) { dwarf = _dwarf; + symbols = NULL; + symbols_sorted_by_name = NULL; cu_offset = dwarf->debug_infoSec->offset; debug_infoSec = new DwrSec (dwarf->debug_infoSec, cu_offset); next_cu_offset = debug_infoSec->ReadLength (); @@ -1883,6 +1885,8 @@ DwrCU::~DwrCU () Destroy (dwrInlinedSubrs); delete srcFiles; delete dwrLineReg; + delete symbols; + delete symbols_sorted_by_name; free (comp_dir); } @@ -2187,9 +2191,80 @@ DwrCU::parse_cu_header (LoadObject *lo) else path = dbe_strdup (dwarf->stabs->path); module->set_name (path); + + // create a list of functions in this CU + Vector <Range *> *ranges = get_ranges (); + if (ranges) + { + Vector <Symbol *> *syms = dwarf->stabs->get_symbols (); + symbols = Symbol::find_symbols (syms, ranges); + symbols_sorted_by_name = Symbol::sort_by_name (syms); + Destroy (ranges); + } return module; } +Vector <Range *> * +DwrCU::get_ranges () +{ + Vector <Range *> *ranges = NULL; + Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_ranges); + if (dwrAttr) + { + Dprintf (DUMP_DWARFLIB, "DwrCU::get_ranges: 0x%llx\n", + (long long) dwrAttr->u.offset); + ranges = dwarf->get_ranges (dwrAttr->u.offset); + } + else + { + uint64_t low_pc = Dwarf_addr (DW_AT_low_pc); + if (low_pc > 0) + { + uint64_t high_pc = get_high_pc (low_pc); + ranges = new Vector <Range *> (1); + ranges->append (new Range (low_pc, high_pc)); + Dprintf (DUMP_DWARFLIB, "DwrCU::get_ranges: pc=0x%llx\n", + (long long) low_pc); + } + } + if (ranges && DUMP_DWARFLIB) + ranges->dump (" "); + return ranges; +} + +void +DwrCU::set_source (Function *func) +{ + int lineno = (int) Dwarf_data (DW_AT_decl_line); + func->setLineFirst (lineno); + + int fileno = (int) Dwarf_data (DW_AT_decl_file); + if (fileno > 0 && fileno < VecSize (srcFiles)) + func->setDefSrc (srcFiles->get (fileno)); +} + +Symbol * +DwrCU::find_declaration (int64_t offset) +{ + int64_t old_offset = dwrTag.offset; + Symbol *sym = NULL; + if (set_die (offset) == DW_DLV_OK) + { + sym = Symbol::get_symbol (symbols_sorted_by_name, get_linkage_name ()); + if (sym && sym->func == NULL) + { + Function *func = sym->createFunction (module); + int lineno = (int) Dwarf_data (DW_AT_decl_line); + func->setLineFirst (lineno); + int fileno = (int) Dwarf_data (DW_AT_decl_file); + if (fileno > 0 && fileno < VecSize (srcFiles)) + func->setDefSrc (srcFiles->get (fileno)); + } + } + set_die (old_offset); + return sym; +} + Dwr_Attr * Dwr_Tag::get_attr (Dwarf_Half attr) { @@ -2357,7 +2432,7 @@ DwrCU::map_dwarf_lines (Module *mod) InlinedSubr *p = func->inlinedSubr + func->inlinedSubrCnt; func->inlinedSubrCnt++; int fileno = inlinedSubr->file - 1; - SourceFile *sf = ((fileno >= 0) && (fileno < VecSize (srcFiles))) ? + SourceFile *sf = ((fileno > 0) && (fileno < VecSize (srcFiles))) ? srcFiles->get (fileno) : dbeSession->get_Unknown_Source (); p->dbeLine = sf->find_dbeline (inlinedSubr->line); p->high_pc = inlinedSubr->high_pc - low_pc; diff --git a/gprofng/src/DwarfLib.h b/gprofng/src/DwarfLib.h index 178801d..230e551 100644 --- a/gprofng/src/DwarfLib.h +++ b/gprofng/src/DwarfLib.h @@ -25,6 +25,8 @@ class ElfReloc; class Dwr_type; +class Function; +class Range; class SourceFile; template <class ITEM> class Vector; @@ -73,12 +75,6 @@ public: return (uint32_t) GetULEB128 (); } - bool - inRange (uint64_t left, uint64_t right) - { - return (offset >= left) && (offset < right); - }; - ElfReloc *reloc; uint64_t sizeSec; uint64_t size; @@ -280,6 +276,8 @@ public: uint64_t cu_header_offset; uint64_t cu_offset; uint64_t next_cu_offset; + Vector<Symbol*> *symbols; // all symbols in this CU are sorted by pc + Vector<Symbol*> *symbols_sorted_by_name; Vector<DwrInlinedSubr*> *dwrInlinedSubrs; Vector<SourceFile *> *srcFiles; bool isMemop; @@ -287,7 +285,10 @@ public: private: void build_abbrevTable (DwrSec *debug_abbrevSec, uint64_t stmt_list_offset); - Function *append_Function (Dwarf_cnt *ctx); + Function *append_Function (Symbol *sym, const char *outerName); + Symbol *find_declaration(int64_t offset); + Vector <Range *> *get_ranges(); + void set_source (Function *func); void parse_inlined_subroutine (Dwarf_cnt *ctx); uint64_t get_low_pc (); uint64_t get_high_pc (uint64_t low_pc); diff --git a/gprofng/src/LoadObject.cc b/gprofng/src/LoadObject.cc index 1ca6ab6..be7ad3a 100644 --- a/gprofng/src/LoadObject.cc +++ b/gprofng/src/LoadObject.cc @@ -20,6 +20,7 @@ #include "config.h" #include <errno.h> +#include <libgen.h> #include "util.h" #include "StringBuilder.h" @@ -303,13 +304,16 @@ LoadObject::dump_functions (FILE *out) { mname = fitem->module ? fitem->module->file_name : noname->file_name; sname = fitem->getDefSrcName (); - fprintf (out, - "id %6llu, @0x%llx - 0x%llx [save 0x%llx] o-%lld sz-%lld %s (module = %s)", - (ull_t) fitem->id, (ull_t) fitem->img_offset, - (ull_t) (fitem->img_offset + fitem->size), - (ull_t) fitem->save_addr, (ull_t) fitem->img_offset, - (ll_t) fitem->size, fitem->get_name (), mname); - if (sname && !streq (sname, mname)) + fprintf (out, "id %6llu, @0x%llx-0x%llx sz-%lld", (ull_t) fitem->id, + (ull_t) fitem->img_offset, + (ull_t) (fitem->img_offset + fitem->size), + (ll_t) fitem->size); + if (fitem->save_addr != 0) + fprintf (out, " [save 0x%llx]", (ull_t) fitem->save_addr); + if (strcmp (fitem->get_mangled_name (), fitem->get_name ()) != 0) + fprintf (out, " [%s]", fitem->get_mangled_name ()); + fprintf (out, " %s (module = %s)", fitem->get_name (), mname); + if (sname && strcmp (basename (sname), basename (mname)) != 0) fprintf (out, " (Source = %s)", sname); fprintf (out, "\n"); } diff --git a/gprofng/src/Makefile.am b/gprofng/src/Makefile.am index 0465cdb..f6d3f5d 100644 --- a/gprofng/src/Makefile.am +++ b/gprofng/src/Makefile.am @@ -78,6 +78,7 @@ CCSOURCES = \ Stabs.cc \ Stats_data.cc \ StringBuilder.cc \ + Symbol.cc \ Table.cc \ QLParser.tab.cc \ dbe_collctrl.cc \ diff --git a/gprofng/src/Makefile.in b/gprofng/src/Makefile.in index 9f07986..0cdd444 100644 --- a/gprofng/src/Makefile.in +++ b/gprofng/src/Makefile.in @@ -174,7 +174,7 @@ am__objects_1 = Application.lo BaseMetric.lo BaseMetricTreeNode.lo \ MemorySpace.lo Metric.lo MetricList.lo Module.lo Ovw_data.lo \ PRBTree.lo PathTree.lo PreviewExp.lo Print.lo \ SAXParserFactory.lo Sample.lo Settings.lo SourceFile.lo \ - Stabs.lo Stats_data.lo StringBuilder.lo Table.lo \ + Stabs.lo Stats_data.lo StringBuilder.lo Symbol.lo Table.lo \ QLParser.tab.lo dbe_collctrl.lo i18n.lo parse.lo UserLabel.lo \ util.lo Dbe.lo am__objects_2 = dbe_hwcdrv.lo dbe_hwcfuncs.lo dbe_hwctable.lo \ @@ -505,6 +505,7 @@ CCSOURCES = \ Stabs.cc \ Stats_data.cc \ StringBuilder.cc \ + Symbol.cc \ Table.cc \ QLParser.tab.cc \ dbe_collctrl.cc \ @@ -777,6 +778,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Stabs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Stats_data.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StringBuilder.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Symbol.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Table.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UserLabel.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/checks.Po@am__quote@ diff --git a/gprofng/src/Stabs.cc b/gprofng/src/Stabs.cc index b98ac28..ff83949 100644 --- a/gprofng/src/Stabs.cc +++ b/gprofng/src/Stabs.cc @@ -35,10 +35,7 @@ #include "StringBuilder.h" #include "DbeFile.h" #include "StringMap.h" - -#define DISASM_REL_NONE 0 /* symtab search only */ -#define DISASM_REL_ONLY 1 /* relocation search only */ -#define DISASM_REL_TARG 2 /* relocatoin then symtab */ +#include "Symbol.h" /////////////////////////////////////////////////////////////////////////////// // class StabReader @@ -62,105 +59,6 @@ private: int StabEntSize; }; -/////////////////////////////////////////////////////////////////////////////// -// class Symbol - -class Symbol -{ -public: - Symbol (Vector<Symbol*> *vec = NULL); - - ~Symbol () - { - free (name); - } - - inline Symbol * - cardinal () - { - return alias ? alias : this; - } - - static void dump (Vector<Symbol*> *vec, char*msg); - - Function *func; - Sp_lang_code lang_code; - uint64_t value; // st_value used in sym_name() - uint64_t save; - int64_t size; - uint64_t img_offset; // image offset in the ELF file - char *name; - Symbol *alias; - int local_ind; - int flags; - bool defined; -}; - -Symbol::Symbol (Vector<Symbol*> *vec) -{ - func = NULL; - lang_code = Sp_lang_unknown; - value = 0; - save = 0; - size = 0; - img_offset = 0; - name = NULL; - alias = NULL; - local_ind = -1; - flags = 0; - defined = false; - if (vec) - vec->append (this); -} - -void -Symbol::dump (Vector<Symbol*> *vec, char*msg) -{ - if (!DUMP_ELF_SYM || vec == NULL || vec->size () == 0) - return; - printf (NTXT ("======= Symbol::dump: %s =========\n" - " value | img_offset | flags|local_ind|\n"), msg); - for (int i = 0; i < vec->size (); i++) - { - Symbol *sp = vec->fetch (i); - printf (NTXT (" %3d %8lld |0x%016llx |%5d |%8d |%s\n"), - i, (long long) sp->value, (long long) sp->img_offset, sp->flags, - sp->local_ind, sp->name ? sp->name : NTXT ("NULL")); - } - printf (NTXT ("\n===== END of Symbol::dump: %s =========\n\n"), msg); -} - -// end of class Symbol -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// class Reloc -class Reloc -{ -public: - Reloc (); - ~Reloc (); - uint64_t type; - uint64_t value; - uint64_t addend; - char *name; -}; - -Reloc::Reloc () -{ - type = 0; - value = 0; - addend = 0; - name = NULL; -} - -Reloc::~Reloc () -{ - free (name); -} -// end of class Reloc -/////////////////////////////////////////////////////////////////////////////// - enum { SYM_PLT = 1 << 0, @@ -232,15 +130,6 @@ SymImgOffsetCmp (const void *a, const void *b) (item1->img_offset == item2->img_offset) ? SymNameCmp (a, b) : -1; } -static int -RelValueCmp (const void *a, const void *b) -{ - Reloc *item1 = *((Reloc **) a); - Reloc *item2 = *((Reloc **) b); - return (item1->value > item2->value) ? 1 : - (item1->value == item2->value) ? 0 : -1; -} - /* Remove all duplicate symbols which can be in SymLst. The duplication is due to processing of both static and dynamic symbols. This function is called before computing symbol @@ -252,7 +141,6 @@ Stabs::removeDupSyms () long ind, i, last; Symbol *symA, *symB; SymLst->sort (SymImgOffsetCmp); - dump (); last = 0; ind = SymLst->size (); @@ -294,8 +182,6 @@ Stabs::Stabs (char *_path, char *_lo_name) SymLstByName = NULL; pltSym = NULL; SymLst = new Vector<Symbol*>; - RelLst = new Vector<Reloc*>; - RelPLTLst = new Vector<Reloc*>; LocalLst = new Vector<Symbol*>; LocalFile = new Vector<char*>; LocalFileIdx = new Vector<int>; @@ -341,8 +227,6 @@ Stabs::~Stabs () { delete SymLstByName; Destroy (SymLst); - Destroy (RelLst); - Destroy (RelPLTLst); Destroy (LocalFile); delete elfDis; delete dwarf; @@ -458,42 +342,6 @@ Stabs::read_symbols (Vector<Function*> *functions) return true; } -char * -Stabs::sym_name (uint64_t target, uint64_t instr, int flag) -{ - long index; - if (flag == DISASM_REL_ONLY || flag == DISASM_REL_TARG) - { - Reloc *relptr = new Reloc; - relptr->value = instr; - index = RelLst->bisearch (0, -1, &relptr, RelValueCmp); - if (index >= 0) - { - delete relptr; - return RelLst->fetch (index)->name; - } - if (!is_relocatable ()) - { - relptr->value = target; - index = RelPLTLst->bisearch (0, -1, &relptr, RelValueCmp); - if (index >= 0) - { - delete relptr; - return RelPLTLst->fetch (index)->name; - } - } - delete relptr; - } - if (flag == DISASM_REL_NONE || flag == DISASM_REL_TARG || !is_relocatable ()) - { - Symbol *sptr; - sptr = map_PC_to_sym (target); - if (sptr && sptr->value == target) - return sptr->name; - } - return NULL; -} - Symbol * Stabs::map_PC_to_sym (uint64_t pc) { @@ -1761,10 +1609,12 @@ Stabs::readSymSec (Elf *elf, bool is_dynamic) if (asym == NULL) break; const char *st_name = bfd_asymbol_name (asym); + if (st_name == NULL) + continue; switch (GELF_ST_TYPE (Sym.st_info)) { case STT_FUNC: - if (Sym.st_size == 0) + if (Sym.st_size == 0 || ELF_ST_BIND (Sym.st_info) == STB_WEAK) break; if (Sym.st_shndx == 0) { @@ -1839,8 +1689,7 @@ Stabs::readSymSec (Elf *elf, bool is_dynamic) fixSymtabAlias (); SymLst->sort (SymValueCmp); get_save_addr (elf->need_swap_endian); - dump (); -}//check_Symtab +} void Stabs::get_save_addr (bool need_swap_endian) @@ -2339,6 +2188,7 @@ Stabs::openDwarf () { dwarf = new Dwarf (this); check_Symtab (); + dump(); } return dwarf; } @@ -2363,8 +2213,8 @@ Stabs::dump () printf (" %3d: %5d '%s'\n", i, LocalFileIdx->fetch (i), LocalFile->fetch (i)); } - Symbol::dump (SymLst, NTXT ("SymLst")); - Symbol::dump (LocalLst, NTXT ("LocalLst")); + SymLst->dump ("SymLst"); + LocalLst->dump ("LocalLst"); printf (NTXT ("\n===== END of Stabs::dump: %s =========\n\n"), path ? path : NTXT ("NULL")); } diff --git a/gprofng/src/Stabs.h b/gprofng/src/Stabs.h index d34741f..c8da278 100644 --- a/gprofng/src/Stabs.h +++ b/gprofng/src/Stabs.h @@ -40,7 +40,6 @@ class ComC; class Elf; class Dwarf; class Symbol; -class Reloc; struct cpf_stabs_t; class SourceFile; template <typename Key_t, typename Value_t> class Map; @@ -86,12 +85,12 @@ class Stabs { Platform_t get_platform() { return platform; } WSize_t get_class() { return wsize;} Stab_status get_status() { return status;} + Vector<Symbol *> *get_symbols() { return SymLst; } Stab_status read_stabs(ino64_t srcInode, Module *module, Vector<ComC*> *comComs, bool readDwarf = false); Stab_status read_archive(LoadObject *lo); bool read_symbols(Vector<Function*> *functions); uint64_t mapOffsetToAddress(uint64_t img_offset); - char *sym_name(uint64_t target, uint64_t instr, int flag); Elf *openElf (bool dbg_info = false); void read_hwcprof_info(Module *module); void dump(); @@ -135,8 +134,6 @@ class Stabs { Symbol *pltSym; Vector<Symbol*> *SymLst; // list of func symbols Vector<Symbol*> *SymLstByName; // list of func symbols sorted by Name - Vector<Reloc*> *RelLst; // list of text relocations - Vector<Reloc*> *RelPLTLst; // list of PLT relocations Vector<Symbol*> *LocalLst; // list of local func symbols Vector<char*> *LocalFile; // list of local files Vector<int> *LocalFileIdx; // start index in LocalLst diff --git a/gprofng/src/Symbol.cc b/gprofng/src/Symbol.cc new file mode 100644 index 0000000..82fe788 --- /dev/null +++ b/gprofng/src/Symbol.cc @@ -0,0 +1,226 @@ +/* Copyright (C) 2025 Free Software Foundation, Inc. + Contributed by Oracle. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "config.h" + +#include "DbeSession.h" +#include "Function.h" +#include "LoadObject.h" +#include "Module.h" +#include "Symbol.h" + + +template<> void Vector<Symbol *>::dump (const char *msg) +{ + if (msg == NULL) + msg = "#"; + Dprintf (1, NTXT ("\n%s Vector<Symbol *> [%lld]\n"), msg, (long long) size ()); + if (size () > 0) + Dprintf (1, " value | img_offset | size | flags|local_ind|\n"); + for (long i = 0, sz = size (); i < sz; i++) + { + Symbol *sp = get (i); + Dprintf (1, " %3ld ", i); + sp->dump (); + } + if (size () > 0) + Dprintf (1, "===== END of Symbol::dump: %s =========\n\n", msg); +} + +void +Symbol::dump (const char *msg) +{ + if (msg) + Dprintf (1, "%s\n", msg); + Dprintf (1, "%8lld |%11lld |%6d |%5d |%8d |%s\n", (long long) value, + (long long) img_offset, (int) size, flags, local_ind, + name ? name : "NULL"); +} + +Symbol::Symbol (Vector<Symbol*> *vec) +{ + func = NULL; + lang_code = Sp_lang_unknown; + value = 0; + save = 0; + size = 0; + img_offset = 0; + name = NULL; + alias = NULL; + local_ind = -1; + flags = 0; + defined = false; + if (vec) + vec->append (this); +} + +Symbol::~Symbol () +{ + free (name); +} + +static int +cmpSym (const void *a, const void *b) +{ + Symbol *item1 = *((Symbol **) a); + Symbol *item2 = *((Symbol **) b); + return (item1->value > item2->value) ? 1 : + (item1->value == item2->value) ? 0 : -1; +} + +static int +cmpSymName (const void *a, const void *b) +{ + Symbol *item1 = *((Symbol **) a); + Symbol *item2 = *((Symbol **) b); + return strcmp (item1->name, item2->name); +} + +Symbol * +Symbol::get_symbol (Vector<Symbol*> *syms, uint64_t pc) +{ + if (syms != NULL && pc != 0) + { + Symbol *sp = new Symbol; + sp->value = pc; + long i = syms->bisearch (0, -1, &sp, cmpSym); + delete sp; + if (i != -1) + return syms->get (i)->cardinal (); + } + return NULL; +} + +Symbol * +Symbol::get_symbol (Vector<Symbol*> *syms, char *linker_name) +{ + if (syms != NULL && linker_name != NULL) + { + Symbol *sp = new Symbol; + sp->name = linker_name; + long i = syms->bisearch (0, -1, &sp, cmpSymName); + sp->name = NULL; + delete sp; + if (i != -1) + return syms->get (i)->cardinal (); + } + return NULL; +} + +Vector<Symbol *> * +Symbol::sort_by_name (Vector<Symbol *> *syms) +{ + if (VecSize (syms) == 0) + return NULL; + Vector<Symbol *> *symbols = syms->copy (); + symbols->sort (cmpSymName); + return symbols; +} + +Vector<Symbol *> * +Symbol::find_symbols (Vector<Symbol*> *syms, Vector<Range *> *ranges) +{ + // 'syms' and 'ranges' must already be sorted. + // return symbols matched by 'ranges' + if (VecSize (syms) == 0 || VecSize (ranges) == 0) + return NULL; + Vector<Symbol *> *symbols = new Vector<Symbol*> (); + + // Use binary search to find a suitable index in 'syms' + int ind = 0; + uint64_t addr = ranges->get (0)->low; + for (int lo = 0, hi = syms->size (); lo < hi;) + { + int mid = (hi + lo) >> 1; + Symbol *sym = syms->get (mid); + if (sym->value == addr) + { + ind = mid; + break; + } + else if (sym->value > addr) + hi = mid - 1; + else + { + ind = mid; + lo = mid + 1; + } + } + + for (int i = 0, r_sz = ranges->size (), sz = syms->size (); ind < sz; ind++) + { + Symbol *sym = syms->get (ind); + while (i < r_sz) + { + Range *r = ranges->get (i); + if (sym->value < r->low) + break; + if (sym->value <= r->high) + { + symbols->append (sym); + break; + } + i++; + } + if (i >= r_sz) + break; + } + if (DUMP_ELF_SYM) + { + syms->dump ( "Symbol::find_symbols: syms"); + symbols->dump ("Symbol::find_symbols: symbols"); + } + if (symbols->size () != 0) + return symbols; + delete symbols; + return NULL; +} + +/* Create and append a new function to the 'module'. + * Copy attributes (size, name, etc) from Simbol, */ +Function * +Symbol::createFunction (Module *module) +{ + if (func) + return func; + func = dbeSession->createFunction (); + func->img_fname = module->file_name; + func->img_offset = img_offset; + func->save_addr = save; + func->size = size; + func->module = module; + func->set_name (name); + module->functions->append (func); + module->loadobject->functions->append (func); + return func; +} + +template<> void Vector<Range *>::dump (const char *msg) +{ + Dprintf (1, NTXT ("%s Vector<Range *> [%lld]\n"), + msg ? msg : "#", (long long) size ()); + for (long i = 0, sz = size (); i < sz; i++) + { + Range *p = get (i); + Dprintf (1, "%3ld 0x%08llx 0x%08llx (%lld - %lld)\n", i, + (long long) p->low, (long long) p->high, + (long long) p->low, (long long) p->high); + } +}
\ No newline at end of file diff --git a/gprofng/src/Symbol.h b/gprofng/src/Symbol.h new file mode 100644 index 0000000..25cceca --- /dev/null +++ b/gprofng/src/Symbol.h @@ -0,0 +1,80 @@ +/* Copyright (C) 2025 Free Software Foundation, Inc. + Contributed by Oracle. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +class Function; +class Module; + +class Range +{ +public: + Range (uint64_t _low, uint64_t _high) + { + low = _low; + high = _high; + } + + inline bool + inside (uint64_t val) + { + return val >= low && val < high; + }; + + uint64_t low; + uint64_t high; +}; + +class Symbol +{ +public: + Symbol (Vector<Symbol *> *vec = NULL); + ~Symbol (); + + Symbol * + cardinal () + { + return alias ? alias : this; + } + + // Find symbols in 'syms' matched by 'ranges'. + static Vector<Symbol *> *find_symbols (Vector<Symbol *> *syms, + Vector<Range *> *ranges); + static Vector<Symbol *> *sort_by_name (Vector<Symbol *> *syms); + + // Find symbol in CU corresponding to pc or linker_name. + static Symbol *get_symbol (Vector<Symbol *> *syms, uint64_t pc); + static Symbol *get_symbol (Vector<Symbol *> *syms, char *linker_name); + + // Create and append a new function to the 'module'. + // Copy attributes (size, name, etc) from Simbol, + Function *createFunction(Module *module); + void dump (const char *msg = NULL); + + Function *func; + Sp_lang_code lang_code; + uint64_t value; + uint64_t save; + int64_t size; + uint64_t img_offset; // image offset in the ELF file + char *name; + Symbol *alias; + int local_ind; + int flags; + bool defined; +};
\ No newline at end of file diff --git a/gprofng/src/collect.h b/gprofng/src/collect.h index 18ab564..3ce6b28 100644 --- a/gprofng/src/collect.h +++ b/gprofng/src/collect.h @@ -32,7 +32,6 @@ class Coll_Ctrl; class Elf; #define MAXLABELS 10 /* maximum number of -C arguments */ -#define STDEBUFSIZE 24000 enum { MAX_LD_PRELOAD_TYPES = 3 }; diff --git a/gprofng/src/envsets.cc b/gprofng/src/envsets.cc index 30803aa..e92c017 100644 --- a/gprofng/src/envsets.cc +++ b/gprofng/src/envsets.cc @@ -31,16 +31,6 @@ #include "StringBuilder.h" #include "Settings.h" -#define STDEBUFSIZE 24000 - -#define LIBGP_COLLECTOR "libgp-collector.so" -#define GPROFNG_PRELOAD_LIBDIRS "GPROFNG_PRELOAD_LIBDIRS" -#define SP_COLLECTOR_EXPNAME "SP_COLLECTOR_EXPNAME" -#define SP_COLLECTOR_FOLLOW_SPEC "SP_COLLECTOR_FOLLOW_SPEC" -#define SP_COLLECTOR_PARAMS "SP_COLLECTOR_PARAMS" -#define SP_COLLECTOR_FOUNDER "SP_COLLECTOR_FOUNDER" -#define SP_COLLECTOR_ORIGIN_COLLECT "SP_COLLECTOR_ORIGIN_COLLECT" - static const char *LD_AUDIT[] = { // "LD_AUDIT", Do not set LD_AUDIT on Linux NULL diff --git a/gprofng/src/gp-collect-app.cc b/gprofng/src/gp-collect-app.cc index b94f410..695c4af 100644 --- a/gprofng/src/gp-collect-app.cc +++ b/gprofng/src/gp-collect-app.cc @@ -44,8 +44,6 @@ #include "collect.h" #include "StringBuilder.h" -#define SP_COLLECTOR_FOUNDER "SP_COLLECTOR_FOUNDER" - extern char **environ; static volatile int interrupt = 0; diff --git a/gprofng/src/ipcio.cc b/gprofng/src/ipcio.cc index 36d2ba5..2890c6a 100644 --- a/gprofng/src/ipcio.cc +++ b/gprofng/src/ipcio.cc @@ -23,10 +23,7 @@ #include <stdlib.h> #include <signal.h> #include <unistd.h> -#include <iostream> -#include <iomanip> -#include <sstream> -#include <queue> + #include "vec.h" #include "util.h" #include "ipcio.h" |