Commit 3cace81e authored by Ingo Molnar's avatar Ingo Molnar

Merge tag 'perf-urgent-for-mingo-20160815' of...

Merge tag 'perf-urgent-for-mingo-20160815' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent

Pull perf/urgent fixes from Arnaldo Carvalho de Melo:

- Fix occasional decoding errors when tracing system-wide with
  Intel PT (Adrian Hunter)

- Fix ip compression in Intel PT for some specific packet types not
  present on current hardware (Adrian Hunter)

- Fix annotation of objects with debuginfo files (Anton Blanchard)

- Fix build on Fedora Rawhide (25) wrt using the right header to
  get the major() & minor() definitions in the jitdump code, now
  it is deprecated getting those using sys/types.h, one has to use
  sys/sysmacros.h (Arnaldo Carvalho de Melo)

- Sync arm64/s390 kvm related header files (Arnaldo Carvalho de Melo)

- Check for dup and fdopen failures in 'perf probe' (Colin Ian King,
  Arnaldo Carvalho de Melo)

- Fix showing callchains in pipe mode, i.e.

    perf record -g -o - workload | perf script

  now shows callchains (He Kuang)

- Show proper message when the scripts directory points to some
  invalid location in 'perf script --list' (He Kuang)

- Fix 'perf mem -t store' to record 'cpu/mem-stores/P' events
  again (Jiri Olsa)

- Fix ppc64le build failure when libelf is not present (Ravi Bangoria)
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 3684b03d 3d918fb1
...@@ -87,9 +87,11 @@ struct kvm_regs { ...@@ -87,9 +87,11 @@ struct kvm_regs {
/* Supported VGICv3 address types */ /* Supported VGICv3 address types */
#define KVM_VGIC_V3_ADDR_TYPE_DIST 2 #define KVM_VGIC_V3_ADDR_TYPE_DIST 2
#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3 #define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
#define KVM_VGIC_ITS_ADDR_TYPE 4
#define KVM_VGIC_V3_DIST_SIZE SZ_64K #define KVM_VGIC_V3_DIST_SIZE SZ_64K
#define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K) #define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
#define KVM_VGIC_V3_ITS_SIZE (2 * SZ_64K)
#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */ #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
#define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */ #define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
......
...@@ -93,6 +93,47 @@ struct kvm_s390_vm_cpu_machine { ...@@ -93,6 +93,47 @@ struct kvm_s390_vm_cpu_machine {
__u64 fac_list[256]; __u64 fac_list[256];
}; };
#define KVM_S390_VM_CPU_PROCESSOR_FEAT 2
#define KVM_S390_VM_CPU_MACHINE_FEAT 3
#define KVM_S390_VM_CPU_FEAT_NR_BITS 1024
#define KVM_S390_VM_CPU_FEAT_ESOP 0
#define KVM_S390_VM_CPU_FEAT_SIEF2 1
#define KVM_S390_VM_CPU_FEAT_64BSCAO 2
#define KVM_S390_VM_CPU_FEAT_SIIF 3
#define KVM_S390_VM_CPU_FEAT_GPERE 4
#define KVM_S390_VM_CPU_FEAT_GSLS 5
#define KVM_S390_VM_CPU_FEAT_IB 6
#define KVM_S390_VM_CPU_FEAT_CEI 7
#define KVM_S390_VM_CPU_FEAT_IBS 8
#define KVM_S390_VM_CPU_FEAT_SKEY 9
#define KVM_S390_VM_CPU_FEAT_CMMA 10
#define KVM_S390_VM_CPU_FEAT_PFMFI 11
#define KVM_S390_VM_CPU_FEAT_SIGPIF 12
struct kvm_s390_vm_cpu_feat {
__u64 feat[16];
};
#define KVM_S390_VM_CPU_PROCESSOR_SUBFUNC 4
#define KVM_S390_VM_CPU_MACHINE_SUBFUNC 5
/* for "test bit" instructions MSB 0 bit ordering, for "query" raw blocks */
struct kvm_s390_vm_cpu_subfunc {
__u8 plo[32]; /* always */
__u8 ptff[16]; /* with TOD-clock steering */
__u8 kmac[16]; /* with MSA */
__u8 kmc[16]; /* with MSA */
__u8 km[16]; /* with MSA */
__u8 kimd[16]; /* with MSA */
__u8 klmd[16]; /* with MSA */
__u8 pckmo[16]; /* with MSA3 */
__u8 kmctr[16]; /* with MSA4 */
__u8 kmf[16]; /* with MSA4 */
__u8 kmo[16]; /* with MSA4 */
__u8 pcc[16]; /* with MSA4 */
__u8 ppno[16]; /* with MSA5 */
__u8 reserved[1824];
};
/* kvm attributes for crypto */ /* kvm attributes for crypto */
#define KVM_S390_VM_CRYPTO_ENABLE_AES_KW 0 #define KVM_S390_VM_CRYPTO_ENABLE_AES_KW 0
#define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW 1 #define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW 1
......
...@@ -140,6 +140,7 @@ ...@@ -140,6 +140,7 @@
exit_code_ipa0(0xB2, 0x4c, "TAR"), \ exit_code_ipa0(0xB2, 0x4c, "TAR"), \
exit_code_ipa0(0xB2, 0x50, "CSP"), \ exit_code_ipa0(0xB2, 0x50, "CSP"), \
exit_code_ipa0(0xB2, 0x54, "MVPG"), \ exit_code_ipa0(0xB2, 0x54, "MVPG"), \
exit_code_ipa0(0xB2, 0x56, "STHYI"), \
exit_code_ipa0(0xB2, 0x58, "BSG"), \ exit_code_ipa0(0xB2, 0x58, "BSG"), \
exit_code_ipa0(0xB2, 0x5a, "BSA"), \ exit_code_ipa0(0xB2, 0x5a, "BSA"), \
exit_code_ipa0(0xB2, 0x5f, "CHSC"), \ exit_code_ipa0(0xB2, 0x5f, "CHSC"), \
......
...@@ -97,6 +97,7 @@ void arch__fix_tev_from_maps(struct perf_probe_event *pev, ...@@ -97,6 +97,7 @@ void arch__fix_tev_from_maps(struct perf_probe_event *pev,
} }
} }
#ifdef HAVE_LIBELF_SUPPORT
void arch__post_process_probe_trace_events(struct perf_probe_event *pev, void arch__post_process_probe_trace_events(struct perf_probe_event *pev,
int ntevs) int ntevs)
{ {
...@@ -118,5 +119,6 @@ void arch__post_process_probe_trace_events(struct perf_probe_event *pev, ...@@ -118,5 +119,6 @@ void arch__post_process_probe_trace_events(struct perf_probe_event *pev,
} }
} }
} }
#endif /* HAVE_LIBELF_SUPPORT */
#endif #endif
...@@ -501,7 +501,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, ...@@ -501,7 +501,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
struct intel_pt_recording *ptr = struct intel_pt_recording *ptr =
container_of(itr, struct intel_pt_recording, itr); container_of(itr, struct intel_pt_recording, itr);
struct perf_pmu *intel_pt_pmu = ptr->intel_pt_pmu; struct perf_pmu *intel_pt_pmu = ptr->intel_pt_pmu;
bool have_timing_info; bool have_timing_info, need_immediate = false;
struct perf_evsel *evsel, *intel_pt_evsel = NULL; struct perf_evsel *evsel, *intel_pt_evsel = NULL;
const struct cpu_map *cpus = evlist->cpus; const struct cpu_map *cpus = evlist->cpus;
bool privileged = geteuid() == 0 || perf_event_paranoid() < 0; bool privileged = geteuid() == 0 || perf_event_paranoid() < 0;
...@@ -655,6 +655,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, ...@@ -655,6 +655,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
ptr->have_sched_switch = 3; ptr->have_sched_switch = 3;
} else { } else {
opts->record_switch_events = true; opts->record_switch_events = true;
need_immediate = true;
if (cpu_wide) if (cpu_wide)
ptr->have_sched_switch = 3; ptr->have_sched_switch = 3;
else else
...@@ -700,6 +701,9 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, ...@@ -700,6 +701,9 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
tracking_evsel->attr.freq = 0; tracking_evsel->attr.freq = 0;
tracking_evsel->attr.sample_period = 1; tracking_evsel->attr.sample_period = 1;
if (need_immediate)
tracking_evsel->immediate = true;
/* In per-cpu case, always need the time of mmap events etc */ /* In per-cpu case, always need the time of mmap events etc */
if (!cpu_map__empty(cpus)) { if (!cpu_map__empty(cpus)) {
perf_evsel__set_sample_bit(tracking_evsel, TIME); perf_evsel__set_sample_bit(tracking_evsel, TIME);
......
...@@ -88,6 +88,9 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem) ...@@ -88,6 +88,9 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem)
if (mem->operation & MEM_OPERATION_LOAD) if (mem->operation & MEM_OPERATION_LOAD)
perf_mem_events[PERF_MEM_EVENTS__LOAD].record = true; perf_mem_events[PERF_MEM_EVENTS__LOAD].record = true;
if (mem->operation & MEM_OPERATION_STORE)
perf_mem_events[PERF_MEM_EVENTS__STORE].record = true;
if (perf_mem_events[PERF_MEM_EVENTS__LOAD].record) if (perf_mem_events[PERF_MEM_EVENTS__LOAD].record)
rec_argv[i++] = "-W"; rec_argv[i++] = "-W";
......
...@@ -371,14 +371,16 @@ static int perf_session__check_output_opt(struct perf_session *session) ...@@ -371,14 +371,16 @@ static int perf_session__check_output_opt(struct perf_session *session)
if (!no_callchain) { if (!no_callchain) {
bool use_callchain = false; bool use_callchain = false;
bool not_pipe = false;
evlist__for_each_entry(session->evlist, evsel) { evlist__for_each_entry(session->evlist, evsel) {
not_pipe = true;
if (evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN) { if (evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN) {
use_callchain = true; use_callchain = true;
break; break;
} }
} }
if (!use_callchain) if (not_pipe && !use_callchain)
symbol_conf.use_callchain = false; symbol_conf.use_callchain = false;
} }
...@@ -1690,8 +1692,13 @@ static int list_available_scripts(const struct option *opt __maybe_unused, ...@@ -1690,8 +1692,13 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path()); snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
scripts_dir = opendir(scripts_path); scripts_dir = opendir(scripts_path);
if (!scripts_dir) if (!scripts_dir) {
return -1; fprintf(stdout,
"open(%s) failed.\n"
"Check \"PERF_EXEC_PATH\" env to set scripts dir.\n",
scripts_path);
exit(-1);
}
for_each_lang(scripts_path, scripts_dir, lang_dirent) { for_each_lang(scripts_path, scripts_dir, lang_dirent) {
snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
......
...@@ -123,8 +123,6 @@ struct intel_pt_decoder { ...@@ -123,8 +123,6 @@ struct intel_pt_decoder {
bool have_calc_cyc_to_tsc; bool have_calc_cyc_to_tsc;
int exec_mode; int exec_mode;
unsigned int insn_bytes; unsigned int insn_bytes;
uint64_t sign_bit;
uint64_t sign_bits;
uint64_t period; uint64_t period;
enum intel_pt_period_type period_type; enum intel_pt_period_type period_type;
uint64_t tot_insn_cnt; uint64_t tot_insn_cnt;
...@@ -191,9 +189,6 @@ struct intel_pt_decoder *intel_pt_decoder_new(struct intel_pt_params *params) ...@@ -191,9 +189,6 @@ struct intel_pt_decoder *intel_pt_decoder_new(struct intel_pt_params *params)
decoder->data = params->data; decoder->data = params->data;
decoder->return_compression = params->return_compression; decoder->return_compression = params->return_compression;
decoder->sign_bit = (uint64_t)1 << 47;
decoder->sign_bits = ~(((uint64_t)1 << 48) - 1);
decoder->period = params->period; decoder->period = params->period;
decoder->period_type = params->period_type; decoder->period_type = params->period_type;
...@@ -362,21 +357,30 @@ int intel_pt__strerror(int code, char *buf, size_t buflen) ...@@ -362,21 +357,30 @@ int intel_pt__strerror(int code, char *buf, size_t buflen)
return 0; return 0;
} }
static uint64_t intel_pt_calc_ip(struct intel_pt_decoder *decoder, static uint64_t intel_pt_calc_ip(const struct intel_pt_pkt *packet,
const struct intel_pt_pkt *packet,
uint64_t last_ip) uint64_t last_ip)
{ {
uint64_t ip; uint64_t ip;
switch (packet->count) { switch (packet->count) {
case 2: case 1:
ip = (last_ip & (uint64_t)0xffffffffffff0000ULL) | ip = (last_ip & (uint64_t)0xffffffffffff0000ULL) |
packet->payload; packet->payload;
break; break;
case 4: case 2:
ip = (last_ip & (uint64_t)0xffffffff00000000ULL) | ip = (last_ip & (uint64_t)0xffffffff00000000ULL) |
packet->payload; packet->payload;
break; break;
case 3:
ip = packet->payload;
/* Sign-extend 6-byte ip */
if (ip & (uint64_t)0x800000000000ULL)
ip |= (uint64_t)0xffff000000000000ULL;
break;
case 4:
ip = (last_ip & (uint64_t)0xffff000000000000ULL) |
packet->payload;
break;
case 6: case 6:
ip = packet->payload; ip = packet->payload;
break; break;
...@@ -384,16 +388,12 @@ static uint64_t intel_pt_calc_ip(struct intel_pt_decoder *decoder, ...@@ -384,16 +388,12 @@ static uint64_t intel_pt_calc_ip(struct intel_pt_decoder *decoder,
return 0; return 0;
} }
if (ip & decoder->sign_bit)
return ip | decoder->sign_bits;
return ip; return ip;
} }
static inline void intel_pt_set_last_ip(struct intel_pt_decoder *decoder) static inline void intel_pt_set_last_ip(struct intel_pt_decoder *decoder)
{ {
decoder->last_ip = intel_pt_calc_ip(decoder, &decoder->packet, decoder->last_ip = intel_pt_calc_ip(&decoder->packet, decoder->last_ip);
decoder->last_ip);
} }
static inline void intel_pt_set_ip(struct intel_pt_decoder *decoder) static inline void intel_pt_set_ip(struct intel_pt_decoder *decoder)
...@@ -1657,6 +1657,12 @@ static int intel_pt_walk_trace(struct intel_pt_decoder *decoder) ...@@ -1657,6 +1657,12 @@ static int intel_pt_walk_trace(struct intel_pt_decoder *decoder)
} }
} }
static inline bool intel_pt_have_ip(struct intel_pt_decoder *decoder)
{
return decoder->last_ip || decoder->packet.count == 0 ||
decoder->packet.count == 3 || decoder->packet.count == 6;
}
/* Walk PSB+ packets to get in sync. */ /* Walk PSB+ packets to get in sync. */
static int intel_pt_walk_psb(struct intel_pt_decoder *decoder) static int intel_pt_walk_psb(struct intel_pt_decoder *decoder)
{ {
...@@ -1677,8 +1683,7 @@ static int intel_pt_walk_psb(struct intel_pt_decoder *decoder) ...@@ -1677,8 +1683,7 @@ static int intel_pt_walk_psb(struct intel_pt_decoder *decoder)
case INTEL_PT_FUP: case INTEL_PT_FUP:
decoder->pge = true; decoder->pge = true;
if (decoder->last_ip || decoder->packet.count == 6 || if (intel_pt_have_ip(decoder)) {
decoder->packet.count == 0) {
uint64_t current_ip = decoder->ip; uint64_t current_ip = decoder->ip;
intel_pt_set_ip(decoder); intel_pt_set_ip(decoder);
...@@ -1767,8 +1772,7 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder) ...@@ -1767,8 +1772,7 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder)
case INTEL_PT_TIP_PGE: case INTEL_PT_TIP_PGE:
case INTEL_PT_TIP: case INTEL_PT_TIP:
decoder->pge = decoder->packet.type != INTEL_PT_TIP_PGD; decoder->pge = decoder->packet.type != INTEL_PT_TIP_PGD;
if (decoder->last_ip || decoder->packet.count == 6 || if (intel_pt_have_ip(decoder))
decoder->packet.count == 0)
intel_pt_set_ip(decoder); intel_pt_set_ip(decoder);
if (decoder->ip) if (decoder->ip)
return 0; return 0;
...@@ -1776,9 +1780,7 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder) ...@@ -1776,9 +1780,7 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder)
case INTEL_PT_FUP: case INTEL_PT_FUP:
if (decoder->overflow) { if (decoder->overflow) {
if (decoder->last_ip || if (intel_pt_have_ip(decoder))
decoder->packet.count == 6 ||
decoder->packet.count == 0)
intel_pt_set_ip(decoder); intel_pt_set_ip(decoder);
if (decoder->ip) if (decoder->ip)
return 0; return 0;
......
...@@ -292,36 +292,46 @@ static int intel_pt_get_ip(enum intel_pt_pkt_type type, unsigned int byte, ...@@ -292,36 +292,46 @@ static int intel_pt_get_ip(enum intel_pt_pkt_type type, unsigned int byte,
const unsigned char *buf, size_t len, const unsigned char *buf, size_t len,
struct intel_pt_pkt *packet) struct intel_pt_pkt *packet)
{ {
switch (byte >> 5) { int ip_len;
packet->count = byte >> 5;
switch (packet->count) {
case 0: case 0:
packet->count = 0; ip_len = 0;
break; break;
case 1: case 1:
if (len < 3) if (len < 3)
return INTEL_PT_NEED_MORE_BYTES; return INTEL_PT_NEED_MORE_BYTES;
packet->count = 2; ip_len = 2;
packet->payload = le16_to_cpu(*(uint16_t *)(buf + 1)); packet->payload = le16_to_cpu(*(uint16_t *)(buf + 1));
break; break;
case 2: case 2:
if (len < 5) if (len < 5)
return INTEL_PT_NEED_MORE_BYTES; return INTEL_PT_NEED_MORE_BYTES;
packet->count = 4; ip_len = 4;
packet->payload = le32_to_cpu(*(uint32_t *)(buf + 1)); packet->payload = le32_to_cpu(*(uint32_t *)(buf + 1));
break; break;
case 3: case 3:
case 6: case 4:
if (len < 7) if (len < 7)
return INTEL_PT_NEED_MORE_BYTES; return INTEL_PT_NEED_MORE_BYTES;
packet->count = 6; ip_len = 6;
memcpy_le64(&packet->payload, buf + 1, 6); memcpy_le64(&packet->payload, buf + 1, 6);
break; break;
case 6:
if (len < 9)
return INTEL_PT_NEED_MORE_BYTES;
ip_len = 8;
packet->payload = le64_to_cpu(*(uint64_t *)(buf + 1));
break;
default: default:
return INTEL_PT_BAD_PACKET; return INTEL_PT_BAD_PACKET;
} }
packet->type = type; packet->type = type;
return packet->count + 1; return ip_len + 1;
} }
static int intel_pt_get_mode(const unsigned char *buf, size_t len, static int intel_pt_get_mode(const unsigned char *buf, size_t len,
......
#include <sys/sysmacros.h>
#include <sys/types.h> #include <sys/types.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
......
...@@ -133,7 +133,7 @@ int probe_file__open_both(int *kfd, int *ufd, int flag) ...@@ -133,7 +133,7 @@ int probe_file__open_both(int *kfd, int *ufd, int flag)
/* Get raw string list of current kprobe_events or uprobe_events */ /* Get raw string list of current kprobe_events or uprobe_events */
struct strlist *probe_file__get_rawlist(int fd) struct strlist *probe_file__get_rawlist(int fd)
{ {
int ret, idx; int ret, idx, fddup;
FILE *fp; FILE *fp;
char buf[MAX_CMDLEN]; char buf[MAX_CMDLEN];
char *p; char *p;
...@@ -143,8 +143,17 @@ struct strlist *probe_file__get_rawlist(int fd) ...@@ -143,8 +143,17 @@ struct strlist *probe_file__get_rawlist(int fd)
return NULL; return NULL;
sl = strlist__new(NULL, NULL); sl = strlist__new(NULL, NULL);
if (sl == NULL)
return NULL;
fddup = dup(fd);
if (fddup < 0)
goto out_free_sl;
fp = fdopen(fddup, "r");
if (!fp)
goto out_close_fddup;
fp = fdopen(dup(fd), "r");
while (!feof(fp)) { while (!feof(fp)) {
p = fgets(buf, MAX_CMDLEN, fp); p = fgets(buf, MAX_CMDLEN, fp);
if (!p) if (!p)
...@@ -156,13 +165,21 @@ struct strlist *probe_file__get_rawlist(int fd) ...@@ -156,13 +165,21 @@ struct strlist *probe_file__get_rawlist(int fd)
ret = strlist__add(sl, buf); ret = strlist__add(sl, buf);
if (ret < 0) { if (ret < 0) {
pr_debug("strlist__add failed (%d)\n", ret); pr_debug("strlist__add failed (%d)\n", ret);
strlist__delete(sl); goto out_close_fp;
return NULL;
} }
} }
fclose(fp); fclose(fp);
return sl; return sl;
out_close_fp:
fclose(fp);
goto out_free_sl;
out_close_fddup:
close(fddup);
out_free_sl:
strlist__delete(sl);
return NULL;
} }
static struct strlist *__probe_file__get_namelist(int fd, bool include_group) static struct strlist *__probe_file__get_namelist(int fd, bool include_group)
...@@ -447,12 +464,17 @@ static int probe_cache__load(struct probe_cache *pcache) ...@@ -447,12 +464,17 @@ static int probe_cache__load(struct probe_cache *pcache)
{ {
struct probe_cache_entry *entry = NULL; struct probe_cache_entry *entry = NULL;
char buf[MAX_CMDLEN], *p; char buf[MAX_CMDLEN], *p;
int ret = 0; int ret = 0, fddup;
FILE *fp; FILE *fp;
fp = fdopen(dup(pcache->fd), "r"); fddup = dup(pcache->fd);
if (!fp) if (fddup < 0)
return -errno;
fp = fdopen(fddup, "r");
if (!fp) {
close(fddup);
return -EINVAL; return -EINVAL;
}
while (!feof(fp)) { while (!feof(fp)) {
if (!fgets(buf, MAX_CMDLEN, fp)) if (!fgets(buf, MAX_CMDLEN, fp))
......
...@@ -837,7 +837,8 @@ int dso__load_sym(struct dso *dso, struct map *map, ...@@ -837,7 +837,8 @@ int dso__load_sym(struct dso *dso, struct map *map,
sec = syms_ss->symtab; sec = syms_ss->symtab;
shdr = syms_ss->symshdr; shdr = syms_ss->symshdr;
if (elf_section_by_name(elf, &ehdr, &tshdr, ".text", NULL)) if (elf_section_by_name(runtime_ss->elf, &runtime_ss->ehdr, &tshdr,
".text", NULL))
dso->text_offset = tshdr.sh_addr - tshdr.sh_offset; dso->text_offset = tshdr.sh_addr - tshdr.sh_offset;
if (runtime_ss->opdsec) if (runtime_ss->opdsec)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment