Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf dso: Add support for reading the e_machine type for a dso

For ELF file dsos read the e_machine from the ELF header. For kernel
types assume the e_machine matches the perf tool. In other cases
return EM_NONE.

When reading from the ELF header use DSO__SWAP that may need
dso->needs_swap initializing. Factor out dso__swap_init to allow this.

Signed-off-by: Ian Rogers <irogers@google.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Arnaldo Carvalho de Melo <acme@kernel.org>
Link: https://lore.kernel.org/r/20250319050741.269828-7-irogers@google.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>

authored by

Ian Rogers and committed by
Namhyung Kim
afffec6f 5c2938fe

+92 -27
+89
tools/perf/util/dso.c
··· 1194 1194 return data_read_write_offset(dso, machine, offset, data, size, true); 1195 1195 } 1196 1196 1197 + uint16_t dso__e_machine(struct dso *dso, struct machine *machine) 1198 + { 1199 + uint16_t e_machine = EM_NONE; 1200 + int fd; 1201 + 1202 + switch (dso__binary_type(dso)) { 1203 + case DSO_BINARY_TYPE__KALLSYMS: 1204 + case DSO_BINARY_TYPE__GUEST_KALLSYMS: 1205 + case DSO_BINARY_TYPE__VMLINUX: 1206 + case DSO_BINARY_TYPE__GUEST_VMLINUX: 1207 + case DSO_BINARY_TYPE__GUEST_KMODULE: 1208 + case DSO_BINARY_TYPE__GUEST_KMODULE_COMP: 1209 + case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE: 1210 + case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP: 1211 + case DSO_BINARY_TYPE__KCORE: 1212 + case DSO_BINARY_TYPE__GUEST_KCORE: 1213 + case DSO_BINARY_TYPE__BPF_PROG_INFO: 1214 + case DSO_BINARY_TYPE__BPF_IMAGE: 1215 + case DSO_BINARY_TYPE__OOL: 1216 + case DSO_BINARY_TYPE__JAVA_JIT: 1217 + return EM_HOST; 1218 + case DSO_BINARY_TYPE__DEBUGLINK: 1219 + case DSO_BINARY_TYPE__BUILD_ID_CACHE: 1220 + case DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO: 1221 + case DSO_BINARY_TYPE__GNU_DEBUGDATA: 1222 + case DSO_BINARY_TYPE__SYSTEM_PATH_DSO: 1223 + case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO: 1224 + case DSO_BINARY_TYPE__FEDORA_DEBUGINFO: 1225 + case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO: 1226 + case DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO: 1227 + case DSO_BINARY_TYPE__BUILDID_DEBUGINFO: 1228 + break; 1229 + case DSO_BINARY_TYPE__NOT_FOUND: 1230 + default: 1231 + return EM_NONE; 1232 + } 1233 + 1234 + mutex_lock(dso__data_open_lock()); 1235 + 1236 + /* 1237 + * dso__data(dso)->fd might be closed if other thread opened another 1238 + * file (dso) due to open file limit (RLIMIT_NOFILE). 1239 + */ 1240 + try_to_open_dso(dso, machine); 1241 + fd = dso__data(dso)->fd; 1242 + if (fd >= 0) { 1243 + _Static_assert(offsetof(Elf32_Ehdr, e_machine) == 18, "Unexpected offset"); 1244 + _Static_assert(offsetof(Elf64_Ehdr, e_machine) == 18, "Unexpected offset"); 1245 + if (dso__needs_swap(dso) == DSO_SWAP__UNSET) { 1246 + unsigned char eidata; 1247 + 1248 + if (pread(fd, &eidata, sizeof(eidata), EI_DATA) == sizeof(eidata)) 1249 + dso__swap_init(dso, eidata); 1250 + } 1251 + if (dso__needs_swap(dso) != DSO_SWAP__UNSET && 1252 + pread(fd, &e_machine, sizeof(e_machine), 18) == sizeof(e_machine)) 1253 + e_machine = DSO__SWAP(dso, uint16_t, e_machine); 1254 + } 1255 + mutex_unlock(dso__data_open_lock()); 1256 + return e_machine; 1257 + } 1258 + 1197 1259 /** 1198 1260 * dso__data_read_addr - Read data from dso address 1199 1261 * @dso: dso object ··· 1609 1547 dso__delete(dso); 1610 1548 else 1611 1549 RC_CHK_PUT(dso); 1550 + } 1551 + 1552 + int dso__swap_init(struct dso *dso, unsigned char eidata) 1553 + { 1554 + static unsigned int const endian = 1; 1555 + 1556 + dso__set_needs_swap(dso, DSO_SWAP__NO); 1557 + 1558 + switch (eidata) { 1559 + case ELFDATA2LSB: 1560 + /* We are big endian, DSO is little endian. */ 1561 + if (*(unsigned char const *)&endian != 1) 1562 + dso__set_needs_swap(dso, DSO_SWAP__YES); 1563 + break; 1564 + 1565 + case ELFDATA2MSB: 1566 + /* We are little endian, DSO is big endian. */ 1567 + if (*(unsigned char const *)&endian != 0) 1568 + dso__set_needs_swap(dso, DSO_SWAP__YES); 1569 + break; 1570 + 1571 + default: 1572 + pr_err("unrecognized DSO data encoding %d\n", eidata); 1573 + return -EINVAL; 1574 + } 1575 + 1576 + return 0; 1612 1577 } 1613 1578 1614 1579 void dso__set_build_id(struct dso *dso, struct build_id *bid)
+3
tools/perf/util/dso.h
··· 737 737 void dso__set_sorted_by_name(struct dso *dso); 738 738 void dso__sort_by_name(struct dso *dso); 739 739 740 + int dso__swap_init(struct dso *dso, unsigned char eidata); 741 + 740 742 void dso__set_build_id(struct dso *dso, struct build_id *bid); 741 743 bool dso__build_id_equal(const struct dso *dso, struct build_id *bid); 742 744 void dso__read_running_kernel_build_id(struct dso *dso, ··· 828 826 off_t dso__data_size(struct dso *dso, struct machine *machine); 829 827 ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, 830 828 u64 offset, u8 *data, ssize_t size); 829 + uint16_t dso__e_machine(struct dso *dso, struct machine *machine); 831 830 ssize_t dso__data_read_addr(struct dso *dso, struct map *map, 832 831 struct machine *machine, u64 addr, 833 832 u8 *data, ssize_t size);
-27
tools/perf/util/symbol-elf.c
··· 1174 1174 1175 1175 #endif 1176 1176 1177 - static int dso__swap_init(struct dso *dso, unsigned char eidata) 1178 - { 1179 - static unsigned int const endian = 1; 1180 - 1181 - dso__set_needs_swap(dso, DSO_SWAP__NO); 1182 - 1183 - switch (eidata) { 1184 - case ELFDATA2LSB: 1185 - /* We are big endian, DSO is little endian. */ 1186 - if (*(unsigned char const *)&endian != 1) 1187 - dso__set_needs_swap(dso, DSO_SWAP__YES); 1188 - break; 1189 - 1190 - case ELFDATA2MSB: 1191 - /* We are little endian, DSO is big endian. */ 1192 - if (*(unsigned char const *)&endian != 0) 1193 - dso__set_needs_swap(dso, DSO_SWAP__YES); 1194 - break; 1195 - 1196 - default: 1197 - pr_err("unrecognized DSO data encoding %d\n", eidata); 1198 - return -EINVAL; 1199 - } 1200 - 1201 - return 0; 1202 - } 1203 - 1204 1177 bool symsrc__possibly_runtime(struct symsrc *ss) 1205 1178 { 1206 1179 return ss->dynsym || ss->opdsec;