aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/version.h2
-rw-r--r--binutils/resbin.c188
-rw-r--r--binutils/rescoff.c32
-rw-r--r--binutils/resrc.c221
-rw-r--r--binutils/resres.c22
-rw-r--r--binutils/windint.h6
-rw-r--r--binutils/windres.c37
-rw-r--r--gas/input-scrub.c27
-rw-r--r--gdb/cp-name-parser.y8
-rw-r--r--gdb/doc/guile.texi3
-rw-r--r--gdb/doc/python.texi3
-rw-r--r--gdb/dwarf2/cu.h11
-rw-r--r--gdb/dwarf2/loc.c45
-rw-r--r--gdb/dwarf2/loc.h43
-rw-r--r--gdb/dwarf2/read.c239
-rw-r--r--gdb/gdbtypes.c167
-rw-r--r--gdb/gdbtypes.h43
-rw-r--r--gdb/guile/scm-color.c11
-rw-r--r--gdb/python/py-color.c9
-rw-r--r--gdb/testsuite/gdb.ada/dyn-bit-offset.exp46
-rw-r--r--gdb/testsuite/gdb.ada/dyn-bit-offset/exam.adb45
-rw-r--r--gdb/testsuite/gdb.ada/fixed_points.exp4
-rw-r--r--gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb7
-rw-r--r--gdb/testsuite/gdb.ada/packed_record_2.exp61
-rw-r--r--gdb/testsuite/gdb.ada/packed_record_2/exam.adb51
-rw-r--r--gdb/testsuite/gdb.ada/task_switch_in_core.exp2
-rw-r--r--gdb/testsuite/gdb.base/coredump-filter-build-id.exp2
-rw-r--r--gdb/testsuite/gdb.base/gcore.exp1
-rw-r--r--gdb/testsuite/gdb.base/print-symbol-loading.exp2
-rw-r--r--gdb/testsuite/gdb.base/solib-search.exp2
-rw-r--r--gdb/testsuite/gdb.cp/templates.exp49
-rw-r--r--gdb/testsuite/gdb.guile/scm-color.exp10
-rw-r--r--gdb/testsuite/gdb.python/py-color.exp12
-rw-r--r--gdb/testsuite/gdb.rocm/mi-attach.exp3
-rw-r--r--gdb/testsuite/gdb.tui/corefile-run.exp2
-rw-r--r--gdb/testsuite/lib/gdb.exp18
-rw-r--r--gdb/value.c22
-rw-r--r--gdb/value.h9
-rw-r--r--gprofng/common/gp-experiment.h62
-rw-r--r--gprofng/libcollector/collector.c48
-rw-r--r--gprofng/libcollector/descendants.h14
-rw-r--r--gprofng/libcollector/envmgmt.c3
-rw-r--r--gprofng/libcollector/linetrace.c4
-rw-r--r--gprofng/src/Dwarf.cc205
-rw-r--r--gprofng/src/Dwarf.h2
-rw-r--r--gprofng/src/DwarfLib.cc79
-rw-r--r--gprofng/src/DwarfLib.h15
-rw-r--r--gprofng/src/LoadObject.cc18
-rw-r--r--gprofng/src/Makefile.am1
-rw-r--r--gprofng/src/Makefile.in4
-rw-r--r--gprofng/src/Stabs.cc166
-rw-r--r--gprofng/src/Stabs.h5
-rw-r--r--gprofng/src/Symbol.cc226
-rw-r--r--gprofng/src/Symbol.h80
-rw-r--r--gprofng/src/collect.h1
-rw-r--r--gprofng/src/envsets.cc10
-rw-r--r--gprofng/src/gp-collect-app.cc2
-rw-r--r--gprofng/src/ipcio.cc5
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"