Skip to content
This repository was archived by the owner on Apr 2, 2024. It is now read-only.

Commit 012b950

Browse files
Copy changes from GCC:
2018-04-17 Ian Lance Taylor <iant@golang.org> * backtrace.c (backtrace_full): When testing whether we can allocate memory, call mmap directly, and munmap the memory. 2018-04-04 Jakub Jelinek <jakub@redhat.com> PR other/85161 * elf.c (elf_zlib_fetch): Fix up predefined macro names in test for big endian, only use 32-bit loads if endianity macros are predefined and indicate big or little endian. 2018-02-15 Jakub Jelinek <jakub@redhat.com> PR other/82368 * elf.c (SHT_PROGBITS): Undefine and define. 2018-02-14 Jakub Jelinek <jakub@redhat.com> PR other/82368 * elf.c (EM_PPC64, EF_PPC64_ABI): Undefine and define. (struct elf_ppc64_opd_data): New type. (elf_initialize_syminfo): Add opd argument, handle symbols pointing into the PowerPC64 ELFv1 .opd section. (elf_add): Read .opd section on PowerPC64 ELFv1, pass pointer to structure with .opd data to elf_initialize_syminfo. 2018-01-19 Tony Reix <tony.reix@atos.net> * xcoff.c (xcoff_incl_compare): New function. (xcoff_incl_search): New function. (xcoff_process_linenos): Use bsearch to find include file. (xcoff_initialize_fileline): Sort include file information. Fixes ianlancetaylor#13
1 parent 1779403 commit 012b950

File tree

3 files changed

+146
-24
lines changed

3 files changed

+146
-24
lines changed

backtrace.c

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,26 @@ POSSIBILITY OF SUCH DAMAGE. */
3232

3333
#include "config.h"
3434

35+
#include <unistd.h>
3536
#include <sys/types.h>
3637

38+
#if !BACKTRACE_USES_MALLOC
39+
#include <sys/mman.h>
40+
#endif
41+
3742
#include "unwind.h"
3843
#include "backtrace.h"
44+
#include "backtrace-supported.h"
3945
#include "internal.h"
4046

47+
#ifndef MAP_ANONYMOUS
48+
#define MAP_ANONYMOUS MAP_ANON
49+
#endif
50+
51+
#ifndef MAP_FAILED
52+
#define MAP_FAILED ((void *)-1)
53+
#endif
54+
4155
/* The main backtrace_full routine. */
4256

4357
/* Data passed through _Unwind_Backtrace. */
@@ -104,7 +118,6 @@ backtrace_full (struct backtrace_state *state, int skip,
104118
backtrace_error_callback error_callback, void *data)
105119
{
106120
struct backtrace_data bdata;
107-
void *p;
108121

109122
bdata.skip = skip + 1;
110123
bdata.state = state;
@@ -113,16 +126,25 @@ backtrace_full (struct backtrace_state *state, int skip,
113126
bdata.data = data;
114127
bdata.ret = 0;
115128

116-
/* If we can't allocate any memory at all, don't try to produce
117-
file/line information. */
118-
p = backtrace_alloc (state, 4096, NULL, NULL);
119-
if (p == NULL)
120-
bdata.can_alloc = 0;
121-
else
122-
{
123-
backtrace_free (state, p, 4096, NULL, NULL);
124-
bdata.can_alloc = 1;
125-
}
129+
#if !BACKTRACE_USES_MALLOC
130+
{
131+
size_t pagesize;
132+
void *page;
133+
134+
/* If we can't allocate any memory at all, don't try to produce
135+
file/line information. */
136+
pagesize = getpagesize ();
137+
page = mmap (NULL, pagesize, PROT_READ | PROT_WRITE,
138+
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
139+
if (page == MAP_FAILED)
140+
bdata.can_alloc = 0;
141+
else
142+
{
143+
munmap (page, pagesize);
144+
bdata.can_alloc = 1;
145+
}
146+
}
147+
#endif
126148

127149
_Unwind_Backtrace (unwind, &bdata);
128150
return bdata.ret;

elf.c

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,12 @@ dl_iterate_phdr (int (*callback) (struct dl_phdr_info *,
165165
#undef ELFDATA2MSB
166166
#undef EV_CURRENT
167167
#undef ET_DYN
168+
#undef EM_PPC64
169+
#undef EF_PPC64_ABI
168170
#undef SHN_LORESERVE
169171
#undef SHN_XINDEX
170172
#undef SHN_UNDEF
173+
#undef SHT_PROGBITS
171174
#undef SHT_SYMTAB
172175
#undef SHT_STRTAB
173176
#undef SHT_DYNSYM
@@ -245,6 +248,9 @@ typedef struct {
245248

246249
#define ET_DYN 3
247250

251+
#define EM_PPC64 21
252+
#define EF_PPC64_ABI 3
253+
248254
typedef struct {
249255
b_elf_word sh_name; /* Section name, index in string tbl */
250256
b_elf_word sh_type; /* Type of section */
@@ -262,6 +268,7 @@ typedef struct {
262268
#define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */
263269
#define SHN_XINDEX 0xFFFF /* Section index is held elsewhere */
264270

271+
#define SHT_PROGBITS 1
265272
#define SHT_SYMTAB 2
266273
#define SHT_STRTAB 3
267274
#define SHT_DYNSYM 11
@@ -405,6 +412,20 @@ struct elf_syminfo_data
405412
size_t count;
406413
};
407414

415+
/* Information about PowerPC64 ELFv1 .opd section. */
416+
417+
struct elf_ppc64_opd_data
418+
{
419+
/* Address of the .opd section. */
420+
b_elf_addr addr;
421+
/* Section data. */
422+
const char *data;
423+
/* Size of the .opd section. */
424+
size_t size;
425+
/* Corresponding section view. */
426+
struct backtrace_view view;
427+
};
428+
408429
/* Compute the CRC-32 of BUF/LEN. This uses the CRC used for
409430
.gnu_debuglink files. */
410431

@@ -569,7 +590,8 @@ elf_initialize_syminfo (struct backtrace_state *state,
569590
const unsigned char *symtab_data, size_t symtab_size,
570591
const unsigned char *strtab, size_t strtab_size,
571592
backtrace_error_callback error_callback,
572-
void *data, struct elf_syminfo_data *sdata)
593+
void *data, struct elf_syminfo_data *sdata,
594+
struct elf_ppc64_opd_data *opd)
573595
{
574596
size_t sym_count;
575597
const b_elf_sym *sym;
@@ -620,7 +642,17 @@ elf_initialize_syminfo (struct backtrace_state *state,
620642
return 0;
621643
}
622644
elf_symbols[j].name = (const char *) strtab + sym->st_name;
623-
elf_symbols[j].address = sym->st_value + base_address;
645+
/* Special case PowerPC64 ELFv1 symbols in .opd section, if the symbol
646+
is a function descriptor, read the actual code address from the
647+
descriptor. */
648+
if (opd
649+
&& sym->st_value >= opd->addr
650+
&& sym->st_value < opd->addr + opd->size)
651+
elf_symbols[j].address
652+
= *(const b_elf_addr *) (opd->data + (sym->st_value - opd->addr));
653+
else
654+
elf_symbols[j].address = sym->st_value;
655+
elf_symbols[j].address += base_address;
624656
elf_symbols[j].size = sym->st_size;
625657
++j;
626658
}
@@ -1054,12 +1086,19 @@ elf_zlib_fetch (const unsigned char **ppin, const unsigned char *pinend,
10541086
return 0;
10551087
}
10561088

1089+
#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) \
1090+
&& defined(__ORDER_BIG_ENDIAN__) \
1091+
&& (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ \
1092+
|| __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
10571093
/* We've ensured that PIN is aligned. */
10581094
next = *(const uint32_t *)pin;
10591095

1060-
#if __BYTE_ORDER == __ORDER_BIG_ENDIAN
1096+
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
10611097
next = __builtin_bswap32 (next);
10621098
#endif
1099+
#else
1100+
next = pin[0] | (pin[1] << 8) | (pin[2] << 16) | (pin[3] << 24);
1101+
#endif
10631102

10641103
val |= (uint64_t)next << bits;
10651104
bits += 32;
@@ -2637,6 +2676,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
26372676
int debug_view_valid;
26382677
unsigned int using_debug_view;
26392678
uint16_t *zdebug_table;
2679+
struct elf_ppc64_opd_data opd_data, *opd;
26402680

26412681
if (!debuginfo)
26422682
{
@@ -2655,6 +2695,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
26552695
debuglink_name = NULL;
26562696
debuglink_crc = 0;
26572697
debug_view_valid = 0;
2698+
opd = NULL;
26582699

26592700
if (!backtrace_get_view (state, descriptor, 0, sizeof ehdr, error_callback,
26602701
data, &ehdr_view))
@@ -2857,6 +2898,23 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
28572898
debuglink_crc = *(const uint32_t*)(debuglink_data + crc_offset);
28582899
}
28592900
}
2901+
2902+
/* Read the .opd section on PowerPC64 ELFv1. */
2903+
if (ehdr.e_machine == EM_PPC64
2904+
&& (ehdr.e_flags & EF_PPC64_ABI) < 2
2905+
&& shdr->sh_type == SHT_PROGBITS
2906+
&& strcmp (name, ".opd") == 0)
2907+
{
2908+
if (!backtrace_get_view (state, descriptor, shdr->sh_offset,
2909+
shdr->sh_size, error_callback, data,
2910+
&opd_data.view))
2911+
goto fail;
2912+
2913+
opd = &opd_data;
2914+
opd->addr = shdr->sh_addr;
2915+
opd->data = (const char *) opd_data.view.data;
2916+
opd->size = shdr->sh_size;
2917+
}
28602918
}
28612919

28622920
if (symtab_shndx == 0)
@@ -2898,7 +2956,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
28982956
if (!elf_initialize_syminfo (state, base_address,
28992957
symtab_view.data, symtab_shdr->sh_size,
29002958
strtab_view.data, strtab_shdr->sh_size,
2901-
error_callback, data, sdata))
2959+
error_callback, data, sdata, opd))
29022960
{
29032961
backtrace_free (state, sdata, sizeof *sdata, error_callback, data);
29042962
goto fail;
@@ -2951,6 +3009,12 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
29513009
buildid_view_valid = 0;
29523010
}
29533011

3012+
if (opd)
3013+
{
3014+
backtrace_release_view (state, &opd->view, error_callback, data);
3015+
opd = NULL;
3016+
}
3017+
29543018
if (debuglink_name != NULL)
29553019
{
29563020
int d;
@@ -3139,6 +3203,8 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
31393203
backtrace_release_view (state, &buildid_view, error_callback, data);
31403204
if (debug_view_valid)
31413205
backtrace_release_view (state, &debug_view, error_callback, data);
3206+
if (opd)
3207+
backtrace_release_view (state, &opd->view, error_callback, data);
31423208
if (descriptor != -1)
31433209
backtrace_close (descriptor, error_callback, data);
31443210
return 0;

xcoff.c

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,40 @@ xcoff_fileline (struct backtrace_state *state, uintptr_t pc,
760760
return callback (data, pc, NULL, 0, NULL);
761761
}
762762

763+
/* Compare struct xcoff_incl for qsort. */
764+
765+
static int
766+
xcoff_incl_compare (const void *v1, const void *v2)
767+
{
768+
const struct xcoff_incl *in1 = (const struct xcoff_incl *) v1;
769+
const struct xcoff_incl *in2 = (const struct xcoff_incl *) v2;
770+
771+
if (in1->begin < in2->begin)
772+
return -1;
773+
else if (in1->begin > in2->begin)
774+
return 1;
775+
else
776+
return 0;
777+
}
778+
779+
/* Find a lnnoptr in an include file. */
780+
781+
static int
782+
xcoff_incl_search (const void *vkey, const void *ventry)
783+
{
784+
const uintptr_t *key = (const uintptr_t *) vkey;
785+
const struct xcoff_incl *entry = (const struct xcoff_incl *) ventry;
786+
uintptr_t lnno;
787+
788+
lnno = *key;
789+
if (lnno < entry->begin)
790+
return -1;
791+
else if (lnno > entry->end)
792+
return 1;
793+
else
794+
return 0;
795+
}
796+
763797
/* Add a new mapping to the vector of line mappings that we are
764798
building. Returns 1 on success, 0 on failure. */
765799

@@ -809,7 +843,6 @@ xcoff_process_linenos (struct backtrace_state *state, uintptr_t base_address,
809843
uintptr_t pc;
810844
uint32_t lnno;
811845
int begincl;
812-
size_t i;
813846

814847
aux = (const b_xcoff_auxent *) (fsym + 1);
815848
lnnoptr = aux->x_fcn.x_lnnoptr;
@@ -839,15 +872,13 @@ xcoff_process_linenos (struct backtrace_state *state, uintptr_t base_address,
839872
/* If part of a function other than the beginning comes from an
840873
include file, the line numbers are absolute, rather than
841874
relative to the beginning of the function. */
842-
for (i = 0; i < vec->count; ++i)
843-
{
844-
incl = (struct xcoff_incl *) vec->vec.base + i;
845-
if (incl->begin <= lnnoptr && lnnoptr <= incl->end)
846-
break;
847-
}
875+
incl = (struct xcoff_incl *) bsearch (&lnnoptr, vec->vec.base,
876+
vec->count,
877+
sizeof (struct xcoff_incl),
878+
xcoff_incl_search);
848879
if (begincl == -1)
849-
begincl = (i < vec->count);
850-
if (i < vec->count)
880+
begincl = incl != NULL;
881+
if (incl != NULL)
851882
{
852883
filename = incl->filename;
853884
if (begincl == 1)
@@ -935,6 +966,9 @@ xcoff_initialize_fileline (struct backtrace_state *state,
935966
i += asym->n_numaux;
936967
}
937968

969+
backtrace_qsort (vec.vec.base, vec.count,
970+
sizeof (struct xcoff_incl), xcoff_incl_compare);
971+
938972
filename = NULL;
939973
fsym = NULL;
940974
for (i = 0; i < nsyms; ++i)

0 commit comments

Comments
 (0)