pf2 0.5.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/Cargo.lock +7 -27
  4. data/README.md +1 -1
  5. data/crates/backtrace-sys2/build.rs +1 -4
  6. data/crates/backtrace-sys2/src/libbacktrace/Makefile.am +116 -31
  7. data/crates/backtrace-sys2/src/libbacktrace/Makefile.in +295 -141
  8. data/crates/backtrace-sys2/src/libbacktrace/README.md +11 -1
  9. data/crates/backtrace-sys2/src/libbacktrace/alloc.c +1 -1
  10. data/crates/backtrace-sys2/src/libbacktrace/allocfail.c +1 -1
  11. data/crates/backtrace-sys2/src/libbacktrace/allocfail.sh +1 -1
  12. data/crates/backtrace-sys2/src/libbacktrace/atomic.c +1 -1
  13. data/crates/backtrace-sys2/src/libbacktrace/backtrace-supported.h.in +1 -1
  14. data/crates/backtrace-sys2/src/libbacktrace/backtrace.c +1 -1
  15. data/crates/backtrace-sys2/src/libbacktrace/backtrace.h +12 -12
  16. data/crates/backtrace-sys2/src/libbacktrace/btest.c +24 -8
  17. data/crates/backtrace-sys2/src/libbacktrace/config/libtool.m4 +162 -53
  18. data/crates/backtrace-sys2/src/libbacktrace/config.h.in +3 -0
  19. data/crates/backtrace-sys2/src/libbacktrace/configure +255 -66
  20. data/crates/backtrace-sys2/src/libbacktrace/configure.ac +27 -8
  21. data/crates/backtrace-sys2/src/libbacktrace/dwarf.c +37 -30
  22. data/crates/backtrace-sys2/src/libbacktrace/edtest.c +2 -2
  23. data/crates/backtrace-sys2/src/libbacktrace/edtest2.c +1 -1
  24. data/crates/backtrace-sys2/src/libbacktrace/elf.c +98 -76
  25. data/crates/backtrace-sys2/src/libbacktrace/fileline.c +1 -1
  26. data/crates/backtrace-sys2/src/libbacktrace/install-debuginfo-for-buildid.sh.in +2 -2
  27. data/crates/backtrace-sys2/src/libbacktrace/instrumented_alloc.c +1 -1
  28. data/crates/backtrace-sys2/src/libbacktrace/internal.h +41 -2
  29. data/crates/backtrace-sys2/src/libbacktrace/macho.c +25 -19
  30. data/crates/backtrace-sys2/src/libbacktrace/mmap.c +1 -1
  31. data/crates/backtrace-sys2/src/libbacktrace/mmapio.c +1 -1
  32. data/crates/backtrace-sys2/src/libbacktrace/mtest.c +4 -4
  33. data/crates/backtrace-sys2/src/libbacktrace/nounwind.c +1 -1
  34. data/crates/backtrace-sys2/src/libbacktrace/pecoff.c +192 -26
  35. data/crates/backtrace-sys2/src/libbacktrace/posix.c +1 -1
  36. data/crates/backtrace-sys2/src/libbacktrace/print.c +41 -16
  37. data/crates/backtrace-sys2/src/libbacktrace/read.c +1 -1
  38. data/crates/backtrace-sys2/src/libbacktrace/simple.c +1 -1
  39. data/crates/backtrace-sys2/src/libbacktrace/sort.c +1 -1
  40. data/crates/backtrace-sys2/src/libbacktrace/state.c +1 -1
  41. data/crates/backtrace-sys2/src/libbacktrace/stest.c +1 -1
  42. data/crates/backtrace-sys2/src/libbacktrace/test_format.c +1 -1
  43. data/crates/backtrace-sys2/src/libbacktrace/testlib.c +1 -1
  44. data/crates/backtrace-sys2/src/libbacktrace/testlib.h +1 -1
  45. data/crates/backtrace-sys2/src/libbacktrace/ttest.c +1 -1
  46. data/crates/backtrace-sys2/src/libbacktrace/unittest.c +1 -1
  47. data/crates/backtrace-sys2/src/libbacktrace/unknown.c +1 -1
  48. data/crates/backtrace-sys2/src/libbacktrace/xcoff.c +43 -32
  49. data/crates/backtrace-sys2/src/libbacktrace/xztest.c +2 -2
  50. data/crates/backtrace-sys2/src/libbacktrace/zstdtest.c +1 -1
  51. data/crates/backtrace-sys2/src/libbacktrace/ztest.c +1 -1
  52. data/ext/pf2/Cargo.toml +1 -1
  53. data/ext/pf2/src/lib.rs +1 -0
  54. data/ext/pf2/src/profile.rs +7 -3
  55. data/ext/pf2/src/profile_serializer.rs +6 -13
  56. data/ext/pf2/src/ringbuffer.rs +1 -3
  57. data/ext/pf2/src/ruby_init.rs +1 -4
  58. data/ext/pf2/src/sample.rs +1 -0
  59. data/ext/pf2/src/serialization/profile.rs +47 -0
  60. data/ext/pf2/src/serialization/serializer.rs +325 -0
  61. data/ext/pf2/src/serialization.rs +2 -0
  62. data/ext/pf2/src/session/configuration.rs +2 -1
  63. data/ext/pf2/src/session/new_thread_watcher.rs +1 -1
  64. data/ext/pf2/src/session/ruby_object.rs +1 -5
  65. data/ext/pf2/src/session.rs +20 -19
  66. data/ext/pf2/src/signal_scheduler.rs +12 -7
  67. data/ext/pf2/src/timer_thread_scheduler.rs +11 -3
  68. data/lib/pf2/cli.rb +3 -1
  69. data/lib/pf2/reporter/firefox_profiler.rb +397 -0
  70. data/lib/pf2/reporter/stack_weaver.rb +81 -0
  71. data/lib/pf2/reporter.rb +3 -392
  72. data/lib/pf2/serve.rb +3 -1
  73. data/lib/pf2/session.rb +2 -0
  74. data/lib/pf2/version.rb +3 -1
  75. data/lib/pf2.rb +4 -1
  76. data/rustfmt.toml +1 -0
  77. metadata +13 -12
  78. data/crates/backtrace-sys2/src/libbacktrace/libtool.m4 +0 -7436
  79. data/crates/backtrace-sys2/src/libbacktrace/ltoptions.m4 +0 -369
  80. data/crates/backtrace-sys2/src/libbacktrace/ltsugar.m4 +0 -123
  81. data/crates/backtrace-sys2/src/libbacktrace/ltversion.m4 +0 -23
  82. data/crates/backtrace-sys2/src/libbacktrace/lt~obsolete.m4 +0 -98
@@ -1,5 +1,5 @@
1
1
  /* dwarf.c -- Get file/line information from DWARF for backtraces.
2
- Copyright (C) 2012-2021 Free Software Foundation, Inc.
2
+ Copyright (C) 2012-2024 Free Software Foundation, Inc.
3
3
  Written by Ian Lance Taylor, Google.
4
4
 
5
5
  Redistribution and use in source and binary forms, with or without
@@ -722,8 +722,8 @@ struct dwarf_data
722
722
  struct dwarf_data *next;
723
723
  /* The data for .gnu_debugaltlink. */
724
724
  struct dwarf_data *altlink;
725
- /* The base address for this file. */
726
- uintptr_t base_address;
725
+ /* The base address mapping for this file. */
726
+ struct libbacktrace_base_address base_address;
727
727
  /* A sorted list of address ranges. */
728
728
  struct unit_addrs *addrs;
729
729
  /* Number of address ranges in list. */
@@ -1944,8 +1944,9 @@ update_pcrange (const struct attr* attr, const struct attr_val* val,
1944
1944
  static int
1945
1945
  add_low_high_range (struct backtrace_state *state,
1946
1946
  const struct dwarf_sections *dwarf_sections,
1947
- uintptr_t base_address, int is_bigendian,
1948
- struct unit *u, const struct pcrange *pcrange,
1947
+ struct libbacktrace_base_address base_address,
1948
+ int is_bigendian, struct unit *u,
1949
+ const struct pcrange *pcrange,
1949
1950
  int (*add_range) (struct backtrace_state *state,
1950
1951
  void *rdata, uintptr_t lowpc,
1951
1952
  uintptr_t highpc,
@@ -1980,8 +1981,8 @@ add_low_high_range (struct backtrace_state *state,
1980
1981
 
1981
1982
  /* Add in the base address of the module when recording PC values,
1982
1983
  so that we can look up the PC directly. */
1983
- lowpc += base_address;
1984
- highpc += base_address;
1984
+ lowpc = libbacktrace_add_base (lowpc, base_address);
1985
+ highpc = libbacktrace_add_base (highpc, base_address);
1985
1986
 
1986
1987
  return add_range (state, rdata, lowpc, highpc, error_callback, data, vec);
1987
1988
  }
@@ -1993,7 +1994,7 @@ static int
1993
1994
  add_ranges_from_ranges (
1994
1995
  struct backtrace_state *state,
1995
1996
  const struct dwarf_sections *dwarf_sections,
1996
- uintptr_t base_address, int is_bigendian,
1997
+ struct libbacktrace_base_address base_address, int is_bigendian,
1997
1998
  struct unit *u, uintptr_t base,
1998
1999
  const struct pcrange *pcrange,
1999
2000
  int (*add_range) (struct backtrace_state *state, void *rdata,
@@ -2039,10 +2040,11 @@ add_ranges_from_ranges (
2039
2040
  base = (uintptr_t) high;
2040
2041
  else
2041
2042
  {
2042
- if (!add_range (state, rdata,
2043
- (uintptr_t) low + base + base_address,
2044
- (uintptr_t) high + base + base_address,
2045
- error_callback, data, vec))
2043
+ uintptr_t rl, rh;
2044
+
2045
+ rl = libbacktrace_add_base ((uintptr_t) low + base, base_address);
2046
+ rh = libbacktrace_add_base ((uintptr_t) high + base, base_address);
2047
+ if (!add_range (state, rdata, rl, rh, error_callback, data, vec))
2046
2048
  return 0;
2047
2049
  }
2048
2050
  }
@@ -2060,7 +2062,7 @@ static int
2060
2062
  add_ranges_from_rnglists (
2061
2063
  struct backtrace_state *state,
2062
2064
  const struct dwarf_sections *dwarf_sections,
2063
- uintptr_t base_address, int is_bigendian,
2065
+ struct libbacktrace_base_address base_address, int is_bigendian,
2064
2066
  struct unit *u, uintptr_t base,
2065
2067
  const struct pcrange *pcrange,
2066
2068
  int (*add_range) (struct backtrace_state *state, void *rdata,
@@ -2143,9 +2145,10 @@ add_ranges_from_rnglists (
2143
2145
  u->addrsize, is_bigendian, index,
2144
2146
  error_callback, data, &high))
2145
2147
  return 0;
2146
- if (!add_range (state, rdata, low + base_address,
2147
- high + base_address, error_callback, data,
2148
- vec))
2148
+ if (!add_range (state, rdata,
2149
+ libbacktrace_add_base (low, base_address),
2150
+ libbacktrace_add_base (high, base_address),
2151
+ error_callback, data, vec))
2149
2152
  return 0;
2150
2153
  }
2151
2154
  break;
@@ -2162,7 +2165,7 @@ add_ranges_from_rnglists (
2162
2165
  error_callback, data, &low))
2163
2166
  return 0;
2164
2167
  length = read_uleb128 (&rnglists_buf);
2165
- low += base_address;
2168
+ low = libbacktrace_add_base (low, base_address);
2166
2169
  if (!add_range (state, rdata, low, low + length,
2167
2170
  error_callback, data, vec))
2168
2171
  return 0;
@@ -2176,8 +2179,9 @@ add_ranges_from_rnglists (
2176
2179
 
2177
2180
  low = read_uleb128 (&rnglists_buf);
2178
2181
  high = read_uleb128 (&rnglists_buf);
2179
- if (!add_range (state, rdata, low + base + base_address,
2180
- high + base + base_address,
2182
+ if (!add_range (state, rdata,
2183
+ libbacktrace_add_base (low + base, base_address),
2184
+ libbacktrace_add_base (high + base, base_address),
2181
2185
  error_callback, data, vec))
2182
2186
  return 0;
2183
2187
  }
@@ -2194,9 +2198,10 @@ add_ranges_from_rnglists (
2194
2198
 
2195
2199
  low = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
2196
2200
  high = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
2197
- if (!add_range (state, rdata, low + base_address,
2198
- high + base_address, error_callback, data,
2199
- vec))
2201
+ if (!add_range (state, rdata,
2202
+ libbacktrace_add_base (low, base_address),
2203
+ libbacktrace_add_base (high, base_address),
2204
+ error_callback, data, vec))
2200
2205
  return 0;
2201
2206
  }
2202
2207
  break;
@@ -2208,7 +2213,7 @@ add_ranges_from_rnglists (
2208
2213
 
2209
2214
  low = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
2210
2215
  length = (uintptr_t) read_uleb128 (&rnglists_buf);
2211
- low += base_address;
2216
+ low = libbacktrace_add_base (low, base_address);
2212
2217
  if (!add_range (state, rdata, low, low + length,
2213
2218
  error_callback, data, vec))
2214
2219
  return 0;
@@ -2236,9 +2241,9 @@ add_ranges_from_rnglists (
2236
2241
  static int
2237
2242
  add_ranges (struct backtrace_state *state,
2238
2243
  const struct dwarf_sections *dwarf_sections,
2239
- uintptr_t base_address, int is_bigendian,
2244
+ struct libbacktrace_base_address base_address, int is_bigendian,
2240
2245
  struct unit *u, uintptr_t base, const struct pcrange *pcrange,
2241
- int (*add_range) (struct backtrace_state *state, void *rdata,
2246
+ int (*add_range) (struct backtrace_state *state, void *rdata,
2242
2247
  uintptr_t lowpc, uintptr_t highpc,
2243
2248
  backtrace_error_callback error_callback,
2244
2249
  void *data, void *vec),
@@ -2272,7 +2277,8 @@ add_ranges (struct backtrace_state *state,
2272
2277
  read, 0 if there is some error. */
2273
2278
 
2274
2279
  static int
2275
- find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
2280
+ find_address_ranges (struct backtrace_state *state,
2281
+ struct libbacktrace_base_address base_address,
2276
2282
  struct dwarf_buf *unit_buf,
2277
2283
  const struct dwarf_sections *dwarf_sections,
2278
2284
  int is_bigendian, struct dwarf_data *altlink,
@@ -2427,7 +2433,8 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
2427
2433
  on success, 0 on failure. */
2428
2434
 
2429
2435
  static int
2430
- build_address_map (struct backtrace_state *state, uintptr_t base_address,
2436
+ build_address_map (struct backtrace_state *state,
2437
+ struct libbacktrace_base_address base_address,
2431
2438
  const struct dwarf_sections *dwarf_sections,
2432
2439
  int is_bigendian, struct dwarf_data *altlink,
2433
2440
  backtrace_error_callback error_callback, void *data,
@@ -2646,7 +2653,7 @@ add_line (struct backtrace_state *state, struct dwarf_data *ddata,
2646
2653
 
2647
2654
  /* Add in the base address here, so that we can look up the PC
2648
2655
  directly. */
2649
- ln->pc = pc + ddata->base_address;
2656
+ ln->pc = libbacktrace_add_base (pc, ddata->base_address);
2650
2657
 
2651
2658
  ln->filename = filename;
2652
2659
  ln->lineno = lineno;
@@ -4285,7 +4292,7 @@ dwarf_fileline (struct backtrace_state *state, uintptr_t pc,
4285
4292
 
4286
4293
  static struct dwarf_data *
4287
4294
  build_dwarf_data (struct backtrace_state *state,
4288
- uintptr_t base_address,
4295
+ struct libbacktrace_base_address base_address,
4289
4296
  const struct dwarf_sections *dwarf_sections,
4290
4297
  int is_bigendian,
4291
4298
  struct dwarf_data *altlink,
@@ -4343,7 +4350,7 @@ build_dwarf_data (struct backtrace_state *state,
4343
4350
 
4344
4351
  int
4345
4352
  backtrace_dwarf_add (struct backtrace_state *state,
4346
- uintptr_t base_address,
4353
+ struct libbacktrace_base_address base_address,
4347
4354
  const struct dwarf_sections *dwarf_sections,
4348
4355
  int is_bigendian,
4349
4356
  struct dwarf_data *fileline_altlink,
@@ -1,5 +1,5 @@
1
1
  /* edtest.c -- Test for libbacktrace storage allocation stress handling
2
- Copyright (C) 2017-2021 Free Software Foundation, Inc.
2
+ Copyright (C) 2017-2024 Free Software Foundation, Inc.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
5
5
  modification, are permitted provided that the following conditions are
@@ -43,7 +43,7 @@ POSSIBILITY OF SUCH DAMAGE. */
43
43
 
44
44
  #include "testlib.h"
45
45
 
46
- static int test1 (void) __attribute__ ((noinline, noclone, unused));
46
+ static int test1 (void) __attribute__ ((noinline, noclone, optnone, unused));
47
47
  extern int f2 (int);
48
48
  extern int f3 (int, int);
49
49
 
@@ -1,5 +1,5 @@
1
1
  /* edtest2.c -- Test for libbacktrace storage allocation stress handling (p2)
2
- Copyright (C) 2017-2021 Free Software Foundation, Inc.
2
+ Copyright (C) 2017-2024 Free Software Foundation, Inc.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
5
5
  modification, are permitted provided that the following conditions are
@@ -1,5 +1,5 @@
1
1
  /* elf.c -- Get debug data from an ELF file for backtraces.
2
- Copyright (C) 2012-2021 Free Software Foundation, Inc.
2
+ Copyright (C) 2012-2024 Free Software Foundation, Inc.
3
3
  Written by Ian Lance Taylor, Google.
4
4
 
5
5
  Redistribution and use in source and binary forms, with or without
@@ -589,7 +589,7 @@ elf_nodebug (struct backtrace_state *state, uintptr_t pc,
589
589
  return bdata.ret;
590
590
  }
591
591
 
592
- error_callback (data, "no debug info in ELF executable", -1);
592
+ error_callback (data, "no debug info in ELF executable (make sure to compile with -g)", -1);
593
593
  return 0;
594
594
  }
595
595
 
@@ -633,7 +633,7 @@ elf_symbol_search (const void *vkey, const void *ventry)
633
633
 
634
634
  static int
635
635
  elf_initialize_syminfo (struct backtrace_state *state,
636
- uintptr_t base_address,
636
+ struct libbacktrace_base_address base_address,
637
637
  const unsigned char *symtab_data, size_t symtab_size,
638
638
  const unsigned char *strtab, size_t strtab_size,
639
639
  backtrace_error_callback error_callback,
@@ -699,7 +699,8 @@ elf_initialize_syminfo (struct backtrace_state *state,
699
699
  = *(const b_elf_addr *) (opd->data + (sym->st_value - opd->addr));
700
700
  else
701
701
  elf_symbols[j].address = sym->st_value;
702
- elf_symbols[j].address += base_address;
702
+ elf_symbols[j].address =
703
+ libbacktrace_add_base (elf_symbols[j].address, base_address);
703
704
  elf_symbols[j].size = sym->st_size;
704
705
  ++j;
705
706
  }
@@ -1182,14 +1183,7 @@ elf_fetch_bits_backward (const unsigned char **ppin,
1182
1183
  val = *pval;
1183
1184
 
1184
1185
  if (unlikely (pin <= pinend))
1185
- {
1186
- if (bits == 0)
1187
- {
1188
- elf_uncompress_failed ();
1189
- return 0;
1190
- }
1191
- return 1;
1192
- }
1186
+ return 1;
1193
1187
 
1194
1188
  pin -= 4;
1195
1189
 
@@ -4854,25 +4848,25 @@ elf_zstd_decompress (const unsigned char *pin, size_t sin,
4854
4848
  {
4855
4849
  case 8:
4856
4850
  *pout++ = *plit++;
4857
- /* FALLTHROUGH */
4851
+ ATTRIBUTE_FALLTHROUGH;
4858
4852
  case 7:
4859
4853
  *pout++ = *plit++;
4860
- /* FALLTHROUGH */
4854
+ ATTRIBUTE_FALLTHROUGH;
4861
4855
  case 6:
4862
4856
  *pout++ = *plit++;
4863
- /* FALLTHROUGH */
4857
+ ATTRIBUTE_FALLTHROUGH;
4864
4858
  case 5:
4865
4859
  *pout++ = *plit++;
4866
- /* FALLTHROUGH */
4860
+ ATTRIBUTE_FALLTHROUGH;
4867
4861
  case 4:
4868
4862
  *pout++ = *plit++;
4869
- /* FALLTHROUGH */
4863
+ ATTRIBUTE_FALLTHROUGH;
4870
4864
  case 3:
4871
4865
  *pout++ = *plit++;
4872
- /* FALLTHROUGH */
4866
+ ATTRIBUTE_FALLTHROUGH;
4873
4867
  case 2:
4874
4868
  *pout++ = *plit++;
4875
- /* FALLTHROUGH */
4869
+ ATTRIBUTE_FALLTHROUGH;
4876
4870
  case 1:
4877
4871
  *pout++ = *plit++;
4878
4872
  break;
@@ -5076,7 +5070,7 @@ elf_uncompress_chdr (struct backtrace_state *state,
5076
5070
  backtrace_error_callback error_callback, void *data,
5077
5071
  unsigned char **uncompressed, size_t *uncompressed_size)
5078
5072
  {
5079
- const b_elf_chdr *chdr;
5073
+ b_elf_chdr chdr;
5080
5074
  char *alc;
5081
5075
  size_t alc_len;
5082
5076
  unsigned char *po;
@@ -5088,27 +5082,30 @@ elf_uncompress_chdr (struct backtrace_state *state,
5088
5082
  if (compressed_size < sizeof (b_elf_chdr))
5089
5083
  return 1;
5090
5084
 
5091
- chdr = (const b_elf_chdr *) compressed;
5085
+ /* The lld linker can misalign a compressed section, so we can't safely read
5086
+ the fields directly as we can for other ELF sections. See
5087
+ https://github.com/ianlancetaylor/libbacktrace/pull/120. */
5088
+ memcpy (&chdr, compressed, sizeof (b_elf_chdr));
5092
5089
 
5093
5090
  alc = NULL;
5094
5091
  alc_len = 0;
5095
- if (*uncompressed != NULL && *uncompressed_size >= chdr->ch_size)
5092
+ if (*uncompressed != NULL && *uncompressed_size >= chdr.ch_size)
5096
5093
  po = *uncompressed;
5097
5094
  else
5098
5095
  {
5099
- alc_len = chdr->ch_size;
5096
+ alc_len = chdr.ch_size;
5100
5097
  alc = backtrace_alloc (state, alc_len, error_callback, data);
5101
5098
  if (alc == NULL)
5102
5099
  return 0;
5103
5100
  po = (unsigned char *) alc;
5104
5101
  }
5105
5102
 
5106
- switch (chdr->ch_type)
5103
+ switch (chdr.ch_type)
5107
5104
  {
5108
5105
  case ELFCOMPRESS_ZLIB:
5109
5106
  if (!elf_zlib_inflate_and_verify (compressed + sizeof (b_elf_chdr),
5110
5107
  compressed_size - sizeof (b_elf_chdr),
5111
- zdebug_table, po, chdr->ch_size))
5108
+ zdebug_table, po, chdr.ch_size))
5112
5109
  goto skip;
5113
5110
  break;
5114
5111
 
@@ -5116,7 +5113,7 @@ elf_uncompress_chdr (struct backtrace_state *state,
5116
5113
  if (!elf_zstd_decompress (compressed + sizeof (b_elf_chdr),
5117
5114
  compressed_size - sizeof (b_elf_chdr),
5118
5115
  (unsigned char *)zdebug_table, po,
5119
- chdr->ch_size))
5116
+ chdr.ch_size))
5120
5117
  goto skip;
5121
5118
  break;
5122
5119
 
@@ -5126,7 +5123,7 @@ elf_uncompress_chdr (struct backtrace_state *state,
5126
5123
  }
5127
5124
 
5128
5125
  *uncompressed = po;
5129
- *uncompressed_size = chdr->ch_size;
5126
+ *uncompressed_size = chdr.ch_size;
5130
5127
 
5131
5128
  return 1;
5132
5129
 
@@ -5568,6 +5565,7 @@ elf_uncompress_lzma_block (const unsigned char *compressed,
5568
5565
  uint64_t header_compressed_size;
5569
5566
  uint64_t header_uncompressed_size;
5570
5567
  unsigned char lzma2_properties;
5568
+ size_t crc_offset;
5571
5569
  uint32_t computed_crc;
5572
5570
  uint32_t stream_crc;
5573
5571
  size_t uncompressed_offset;
@@ -5671,28 +5669,29 @@ elf_uncompress_lzma_block (const unsigned char *compressed,
5671
5669
  /* The properties describe the dictionary size, but we don't care
5672
5670
  what that is. */
5673
5671
 
5674
- /* Block header padding. */
5675
- if (unlikely (off + 4 > compressed_size))
5672
+ /* Skip to just before CRC, verifying zero bytes in between. */
5673
+ crc_offset = block_header_offset + block_header_size - 4;
5674
+ if (unlikely (crc_offset + 4 > compressed_size))
5676
5675
  {
5677
5676
  elf_uncompress_failed ();
5678
5677
  return 0;
5679
5678
  }
5680
-
5681
- off = (off + 3) &~ (size_t) 3;
5682
-
5683
- if (unlikely (off + 4 > compressed_size))
5679
+ for (; off < crc_offset; off++)
5684
5680
  {
5685
- elf_uncompress_failed ();
5686
- return 0;
5681
+ if (compressed[off] != 0)
5682
+ {
5683
+ elf_uncompress_failed ();
5684
+ return 0;
5685
+ }
5687
5686
  }
5688
5687
 
5689
5688
  /* Block header CRC. */
5690
5689
  computed_crc = elf_crc32 (0, compressed + block_header_offset,
5691
5690
  block_header_size - 4);
5692
- stream_crc = (compressed[off]
5693
- | (compressed[off + 1] << 8)
5694
- | (compressed[off + 2] << 16)
5695
- | (compressed[off + 3] << 24));
5691
+ stream_crc = ((uint32_t)compressed[off]
5692
+ | ((uint32_t)compressed[off + 1] << 8)
5693
+ | ((uint32_t)compressed[off + 2] << 16)
5694
+ | ((uint32_t)compressed[off + 3] << 24));
5696
5695
  if (unlikely (computed_crc != stream_crc))
5697
5696
  {
5698
5697
  elf_uncompress_failed ();
@@ -6302,10 +6301,10 @@ elf_uncompress_lzma (struct backtrace_state *state,
6302
6301
 
6303
6302
  /* Next comes a CRC of the stream flags. */
6304
6303
  computed_crc = elf_crc32 (0, compressed + 6, 2);
6305
- stream_crc = (compressed[8]
6306
- | (compressed[9] << 8)
6307
- | (compressed[10] << 16)
6308
- | (compressed[11] << 24));
6304
+ stream_crc = ((uint32_t)compressed[8]
6305
+ | ((uint32_t)compressed[9] << 8)
6306
+ | ((uint32_t)compressed[10] << 16)
6307
+ | ((uint32_t)compressed[11] << 24));
6309
6308
  if (unlikely (computed_crc != stream_crc))
6310
6309
  {
6311
6310
  elf_uncompress_failed ();
@@ -6346,10 +6345,10 @@ elf_uncompress_lzma (struct backtrace_state *state,
6346
6345
 
6347
6346
  /* Before that is a footer CRC. */
6348
6347
  computed_crc = elf_crc32 (0, compressed + offset, 6);
6349
- stream_crc = (compressed[offset - 4]
6350
- | (compressed[offset - 3] << 8)
6351
- | (compressed[offset - 2] << 16)
6352
- | (compressed[offset - 1] << 24));
6348
+ stream_crc = ((uint32_t)compressed[offset - 4]
6349
+ | ((uint32_t)compressed[offset - 3] << 8)
6350
+ | ((uint32_t)compressed[offset - 2] << 16)
6351
+ | ((uint32_t)compressed[offset - 1] << 24));
6353
6352
  if (unlikely (computed_crc != stream_crc))
6354
6353
  {
6355
6354
  elf_uncompress_failed ();
@@ -6405,10 +6404,10 @@ elf_uncompress_lzma (struct backtrace_state *state,
6405
6404
  /* Next is a CRC of the index. */
6406
6405
  computed_crc = elf_crc32 (0, compressed + index_offset,
6407
6406
  offset - index_offset);
6408
- stream_crc = (compressed[offset]
6409
- | (compressed[offset + 1] << 8)
6410
- | (compressed[offset + 2] << 16)
6411
- | (compressed[offset + 3] << 24));
6407
+ stream_crc = ((uint32_t)compressed[offset]
6408
+ | ((uint32_t)compressed[offset + 1] << 8)
6409
+ | ((uint32_t)compressed[offset + 2] << 16)
6410
+ | ((uint32_t)compressed[offset + 3] << 24));
6412
6411
  if (unlikely (computed_crc != stream_crc))
6413
6412
  {
6414
6413
  elf_uncompress_failed ();
@@ -6501,8 +6500,10 @@ backtrace_uncompress_lzma (struct backtrace_state *state,
6501
6500
  static int
6502
6501
  elf_add (struct backtrace_state *state, const char *filename, int descriptor,
6503
6502
  const unsigned char *memory, size_t memory_size,
6504
- uintptr_t base_address, backtrace_error_callback error_callback,
6505
- void *data, fileline *fileline_fn, int *found_sym, int *found_dwarf,
6503
+ struct libbacktrace_base_address base_address,
6504
+ struct elf_ppc64_opd_data *caller_opd,
6505
+ backtrace_error_callback error_callback, void *data,
6506
+ fileline *fileline_fn, int *found_sym, int *found_dwarf,
6506
6507
  struct dwarf_data **fileline_entry, int exe, int debuginfo,
6507
6508
  const char *with_buildid_data, uint32_t with_buildid_size)
6508
6509
  {
@@ -6557,6 +6558,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
6557
6558
  struct elf_view split_debug_view[DEBUG_MAX];
6558
6559
  unsigned char split_debug_view_valid[DEBUG_MAX];
6559
6560
  struct elf_ppc64_opd_data opd_data, *opd;
6561
+ int opd_view_valid;
6560
6562
  struct dwarf_sections dwarf_sections;
6561
6563
 
6562
6564
  if (!debuginfo)
@@ -6584,6 +6586,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
6584
6586
  debug_view_valid = 0;
6585
6587
  memset (&split_debug_view_valid[0], 0, sizeof split_debug_view_valid);
6586
6588
  opd = NULL;
6589
+ opd_view_valid = 0;
6587
6590
 
6588
6591
  if (!elf_get_view (state, descriptor, memory, memory_size, 0, sizeof ehdr,
6589
6592
  error_callback, data, &ehdr_view))
@@ -6840,7 +6843,8 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
6840
6843
  }
6841
6844
  }
6842
6845
 
6843
- if (!gnu_debugdata_view_valid
6846
+ if (!debuginfo
6847
+ && !gnu_debugdata_view_valid
6844
6848
  && strcmp (name, ".gnu_debugdata") == 0)
6845
6849
  {
6846
6850
  if (!elf_get_view (state, descriptor, memory, memory_size,
@@ -6867,12 +6871,18 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
6867
6871
  opd->addr = shdr->sh_addr;
6868
6872
  opd->data = (const char *) opd_data.view.view.data;
6869
6873
  opd->size = shdr->sh_size;
6874
+ opd_view_valid = 1;
6870
6875
  }
6871
6876
  }
6872
6877
 
6878
+ /* A debuginfo file may not have a useful .opd section, but we can use the
6879
+ one from the original executable. */
6880
+ if (opd == NULL)
6881
+ opd = caller_opd;
6882
+
6873
6883
  if (symtab_shndx == 0)
6874
6884
  symtab_shndx = dynsym_shndx;
6875
- if (symtab_shndx != 0 && !debuginfo)
6885
+ if (symtab_shndx != 0)
6876
6886
  {
6877
6887
  const b_elf_shdr *symtab_shdr;
6878
6888
  unsigned int strtab_shndx;
@@ -6948,9 +6958,9 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
6948
6958
  elf_release_view (state, &debuglink_view, error_callback, data);
6949
6959
  if (debugaltlink_view_valid)
6950
6960
  elf_release_view (state, &debugaltlink_view, error_callback, data);
6951
- ret = elf_add (state, "", d, NULL, 0, base_address, error_callback,
6952
- data, fileline_fn, found_sym, found_dwarf, NULL, 0,
6953
- 1, NULL, 0);
6961
+ ret = elf_add (state, "", d, NULL, 0, base_address, opd,
6962
+ error_callback, data, fileline_fn, found_sym,
6963
+ found_dwarf, NULL, 0, 1, NULL, 0);
6954
6964
  if (ret < 0)
6955
6965
  backtrace_close (d, error_callback, data);
6956
6966
  else if (descriptor >= 0)
@@ -6965,12 +6975,6 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
6965
6975
  buildid_view_valid = 0;
6966
6976
  }
6967
6977
 
6968
- if (opd)
6969
- {
6970
- elf_release_view (state, &opd->view, error_callback, data);
6971
- opd = NULL;
6972
- }
6973
-
6974
6978
  if (debuglink_name != NULL)
6975
6979
  {
6976
6980
  int d;
@@ -6985,9 +6989,9 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
6985
6989
  elf_release_view (state, &debuglink_view, error_callback, data);
6986
6990
  if (debugaltlink_view_valid)
6987
6991
  elf_release_view (state, &debugaltlink_view, error_callback, data);
6988
- ret = elf_add (state, "", d, NULL, 0, base_address, error_callback,
6989
- data, fileline_fn, found_sym, found_dwarf, NULL, 0,
6990
- 1, NULL, 0);
6992
+ ret = elf_add (state, "", d, NULL, 0, base_address, opd,
6993
+ error_callback, data, fileline_fn, found_sym,
6994
+ found_dwarf, NULL, 0, 1, NULL, 0);
6991
6995
  if (ret < 0)
6992
6996
  backtrace_close (d, error_callback, data);
6993
6997
  else if (descriptor >= 0)
@@ -7013,7 +7017,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
7013
7017
  {
7014
7018
  int ret;
7015
7019
 
7016
- ret = elf_add (state, filename, d, NULL, 0, base_address,
7020
+ ret = elf_add (state, filename, d, NULL, 0, base_address, opd,
7017
7021
  error_callback, data, fileline_fn, found_sym,
7018
7022
  found_dwarf, &fileline_altlink, 0, 1,
7019
7023
  debugaltlink_buildid_data, debugaltlink_buildid_size);
@@ -7050,7 +7054,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
7050
7054
  if (ret)
7051
7055
  {
7052
7056
  ret = elf_add (state, filename, -1, gnu_debugdata_uncompressed,
7053
- gnu_debugdata_uncompressed_size, base_address,
7057
+ gnu_debugdata_uncompressed_size, base_address, opd,
7054
7058
  error_callback, data, fileline_fn, found_sym,
7055
7059
  found_dwarf, NULL, 0, 0, NULL, 0);
7056
7060
  if (ret >= 0 && descriptor >= 0)
@@ -7059,6 +7063,13 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
7059
7063
  }
7060
7064
  }
7061
7065
 
7066
+ if (opd_view_valid)
7067
+ {
7068
+ elf_release_view (state, &opd->view, error_callback, data);
7069
+ opd_view_valid = 0;
7070
+ opd = NULL;
7071
+ }
7072
+
7062
7073
  /* Read all the debug sections in a single view, since they are
7063
7074
  probably adjacent in the file. If any of sections are
7064
7075
  uncompressed, we never release this view. */
@@ -7305,7 +7316,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
7305
7316
  if (split_debug_view_valid[i])
7306
7317
  elf_release_view (state, &split_debug_view[i], error_callback, data);
7307
7318
  }
7308
- if (opd)
7319
+ if (opd_view_valid)
7309
7320
  elf_release_view (state, &opd->view, error_callback, data);
7310
7321
  if (descriptor >= 0)
7311
7322
  backtrace_close (descriptor, error_callback, data);
@@ -7340,6 +7351,7 @@ phdr_callback (struct dl_phdr_info *info, size_t size ATTRIBUTE_UNUSED,
7340
7351
  const char *filename;
7341
7352
  int descriptor;
7342
7353
  int does_not_exist;
7354
+ struct libbacktrace_base_address base_address;
7343
7355
  fileline elf_fileline_fn;
7344
7356
  int found_dwarf;
7345
7357
 
@@ -7369,7 +7381,8 @@ phdr_callback (struct dl_phdr_info *info, size_t size ATTRIBUTE_UNUSED,
7369
7381
  return 0;
7370
7382
  }
7371
7383
 
7372
- if (elf_add (pd->state, filename, descriptor, NULL, 0, info->dlpi_addr,
7384
+ base_address.m = info->dlpi_addr;
7385
+ if (elf_add (pd->state, filename, descriptor, NULL, 0, base_address, NULL,
7373
7386
  pd->error_callback, pd->data, &elf_fileline_fn, pd->found_sym,
7374
7387
  &found_dwarf, NULL, 0, 0, NULL, 0))
7375
7388
  {
@@ -7398,11 +7411,20 @@ backtrace_initialize (struct backtrace_state *state, const char *filename,
7398
7411
  fileline elf_fileline_fn = elf_nodebug;
7399
7412
  struct phdr_data pd;
7400
7413
 
7401
- ret = elf_add (state, filename, descriptor, NULL, 0, 0, error_callback, data,
7402
- &elf_fileline_fn, &found_sym, &found_dwarf, NULL, 1, 0, NULL,
7403
- 0);
7404
- if (!ret)
7405
- return 0;
7414
+ /* When using fdpic we must use dl_iterate_phdr for all modules, including
7415
+ the main executable, so that we can get the right base address
7416
+ mapping. */
7417
+ if (!libbacktrace_using_fdpic ())
7418
+ {
7419
+ struct libbacktrace_base_address zero_base_address;
7420
+
7421
+ memset (&zero_base_address, 0, sizeof zero_base_address);
7422
+ ret = elf_add (state, filename, descriptor, NULL, 0, zero_base_address,
7423
+ NULL, error_callback, data, &elf_fileline_fn, &found_sym,
7424
+ &found_dwarf, NULL, 1, 0, NULL, 0);
7425
+ if (!ret)
7426
+ return 0;
7427
+ }
7406
7428
 
7407
7429
  pd.state = state;
7408
7430
  pd.error_callback = error_callback;
@@ -1,5 +1,5 @@
1
1
  /* fileline.c -- Get file and line number information in a backtrace.
2
- Copyright (C) 2012-2021 Free Software Foundation, Inc.
2
+ Copyright (C) 2012-2024 Free Software Foundation, Inc.
3
3
  Written by Ian Lance Taylor, Google.
4
4
 
5
5
  Redistribution and use in source and binary forms, with or without
@@ -2,7 +2,7 @@
2
2
 
3
3
  # install-debug-info-for-buildid.sh -- Helper script for libbacktrace library
4
4
  # testing.
5
- # Copyright (C) 2019-2021 Free Software Foundation, Inc.
5
+ # Copyright (C) 2019-2024 Free Software Foundation, Inc.
6
6
 
7
7
  # Redistribution and use in source and binary forms, with or without
8
8
  # modification, are permitted provided that the following conditions are
@@ -47,7 +47,7 @@ mkdir_p="@MKDIR_P@"
47
47
  build_id_dir="$1"
48
48
  src="$2"
49
49
 
50
- buildid=$($readelf -n $src \
50
+ buildid=$(LANG=C $readelf -n $src \
51
51
  | $grep "Build ID" \
52
52
  | $awk '{print $3}')
53
53
 
@@ -1,6 +1,6 @@
1
1
  /* instrumented_alloc.c -- Memory allocation instrumented to fail when
2
2
  requested, for testing purposes.
3
- Copyright (C) 2018-2021 Free Software Foundation, Inc.
3
+ Copyright (C) 2018-2024 Free Software Foundation, Inc.
4
4
 
5
5
  Redistribution and use in source and binary forms, with or without
6
6
  modification, are permitted provided that the following conditions are