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: Factor out e_machine reading for use in thread

Factor out the resilient e_machine reading code in dso so that it may
be used in thread.

As there is no dso in that case, make the dso optional.

This makes some minor other changes as the swap type from the dso cannot
be ascertained.

Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Aditya Bodkhe <aditya.b1@linux.ibm.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Athira Rajeev <atrajeev@linux.ibm.com>
Cc: Chun-Tse Shao <ctshao@google.com>
Cc: Guo Ren <guoren@kernel.org>
Cc: Howard Chu <howardchu95@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sergei Trofimovich <slyich@gmail.com>
Cc: Shimin Guo <shimin.guo@skydio.com>
Cc: Stephen Brennan <stephen.s.brennan@oracle.com>
Cc: Swapnil Sapkal <swapnil.sapkal@amd.com>
Cc: Tianyou Li <tianyou.li@intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Ian Rogers and committed by
Arnaldo Carvalho de Melo
7d0ebeb6 76b2cf07

+74 -49
+67 -41
tools/perf/util/dso.c
··· 1203 1203 return data_read_write_offset(dso, machine, offset, data, size, true); 1204 1204 } 1205 1205 1206 + static enum dso_swap_type dso_swap_type__from_elf_data(unsigned char eidata) 1207 + { 1208 + static const unsigned int endian = 1; 1209 + 1210 + switch (eidata) { 1211 + case ELFDATA2LSB: 1212 + /* We are big endian, DSO is little endian. */ 1213 + return (*(unsigned char const *)&endian != 1) ? DSO_SWAP__YES : DSO_SWAP__NO; 1214 + case ELFDATA2MSB: 1215 + /* We are little endian, DSO is big endian. */ 1216 + return (*(unsigned char const *)&endian != 0) ? DSO_SWAP__YES : DSO_SWAP__NO; 1217 + default: 1218 + return DSO_SWAP__UNSET; 1219 + } 1220 + } 1221 + 1222 + /* Reads e_machine from fd, optionally caching data in dso. */ 1223 + uint16_t dso__read_e_machine(struct dso *optional_dso, int fd) 1224 + { 1225 + uint16_t e_machine = EM_NONE; 1226 + unsigned char e_ident[EI_NIDENT]; 1227 + enum dso_swap_type swap_type; 1228 + 1229 + _Static_assert(offsetof(Elf32_Ehdr, e_ident) == 0, "Unexpected offset"); 1230 + _Static_assert(offsetof(Elf64_Ehdr, e_ident) == 0, "Unexpected offset"); 1231 + if (pread(fd, &e_ident, sizeof(e_ident), 0) != sizeof(e_ident)) 1232 + return EM_NONE; // Read failed. 1233 + 1234 + if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) 1235 + return EM_NONE; // Not an ELF file. 1236 + 1237 + if (e_ident[EI_CLASS] == ELFCLASSNONE || e_ident[EI_CLASS] >= ELFCLASSNUM) 1238 + return EM_NONE; // Bad ELF class (32 or 64-bit objects). 1239 + 1240 + if (e_ident[EI_VERSION] != EV_CURRENT) 1241 + return EM_NONE; // Bad ELF version. 1242 + 1243 + swap_type = dso_swap_type__from_elf_data(e_ident[EI_DATA]); 1244 + if (swap_type == DSO_SWAP__UNSET) 1245 + return EM_NONE; // Bad ELF data encoding. 1246 + 1247 + /* Cache the need for swapping. */ 1248 + if (optional_dso) { 1249 + assert(dso__needs_swap(optional_dso) == DSO_SWAP__UNSET || 1250 + dso__needs_swap(optional_dso) == swap_type); 1251 + dso__set_needs_swap(optional_dso, swap_type); 1252 + } 1253 + 1254 + { 1255 + _Static_assert(offsetof(Elf32_Ehdr, e_machine) == 18, "Unexpected offset"); 1256 + _Static_assert(offsetof(Elf64_Ehdr, e_machine) == 18, "Unexpected offset"); 1257 + if (pread(fd, &e_machine, sizeof(e_machine), 18) != sizeof(e_machine)) 1258 + return EM_NONE; // e_machine read failed. 1259 + } 1260 + 1261 + e_machine = DSO_SWAP_TYPE__SWAP(swap_type, uint16_t, e_machine); 1262 + if (e_machine >= EM_NUM) 1263 + return EM_NONE; // Bad ELF machine number. 1264 + 1265 + return e_machine; 1266 + } 1267 + 1206 1268 uint16_t dso__e_machine(struct dso *dso, struct machine *machine) 1207 1269 { 1208 1270 uint16_t e_machine = EM_NONE; ··· 1310 1248 */ 1311 1249 try_to_open_dso(dso, machine); 1312 1250 fd = dso__data(dso)->fd; 1313 - if (fd >= 0) { 1314 - unsigned char e_ident[EI_NIDENT]; 1251 + if (fd >= 0) 1252 + e_machine = dso__read_e_machine(dso, fd); 1315 1253 1316 - _Static_assert(offsetof(Elf32_Ehdr, e_ident) == 0, "Unexpected offset"); 1317 - _Static_assert(offsetof(Elf64_Ehdr, e_ident) == 0, "Unexpected offset"); 1318 - if (pread(fd, &e_ident, sizeof(e_ident), 0) == sizeof(e_ident) && 1319 - memcmp(e_ident, ELFMAG, SELFMAG) == 0 && 1320 - e_ident[EI_CLASS] > ELFCLASSNONE && e_ident[EI_CLASS] < ELFCLASSNUM && 1321 - e_ident[EI_DATA] > ELFDATANONE && e_ident[EI_DATA] < ELFDATANUM && 1322 - e_ident[EI_VERSION] == EV_CURRENT) { 1323 - _Static_assert(offsetof(Elf32_Ehdr, e_machine) == 18, "Unexpected offset"); 1324 - _Static_assert(offsetof(Elf64_Ehdr, e_machine) == 18, "Unexpected offset"); 1325 - 1326 - if (dso__needs_swap(dso) == DSO_SWAP__UNSET) 1327 - dso__swap_init(dso, e_ident[EI_DATA]); 1328 - 1329 - if (dso__needs_swap(dso) != DSO_SWAP__UNSET && 1330 - pread(fd, &e_machine, sizeof(e_machine), 18) == sizeof(e_machine) && 1331 - e_machine < EM_NUM) 1332 - e_machine = DSO__SWAP(dso, uint16_t, e_machine); 1333 - else 1334 - e_machine = EM_NONE; 1335 - } 1336 - } 1337 1254 mutex_unlock(dso__data_open_lock()); 1338 1255 return e_machine; 1339 1256 } ··· 1697 1656 1698 1657 int dso__swap_init(struct dso *dso, unsigned char eidata) 1699 1658 { 1700 - static unsigned int const endian = 1; 1659 + enum dso_swap_type type = dso_swap_type__from_elf_data(eidata); 1701 1660 1702 - dso__set_needs_swap(dso, DSO_SWAP__NO); 1703 - 1704 - switch (eidata) { 1705 - case ELFDATA2LSB: 1706 - /* We are big endian, DSO is little endian. */ 1707 - if (*(unsigned char const *)&endian != 1) 1708 - dso__set_needs_swap(dso, DSO_SWAP__YES); 1709 - break; 1710 - 1711 - case ELFDATA2MSB: 1712 - /* We are little endian, DSO is big endian. */ 1713 - if (*(unsigned char const *)&endian != 0) 1714 - dso__set_needs_swap(dso, DSO_SWAP__YES); 1715 - break; 1716 - 1717 - default: 1661 + dso__set_needs_swap(dso, type); 1662 + if (type == DSO_SWAP__UNSET) { 1718 1663 pr_err("unrecognized DSO data encoding %d\n", eidata); 1719 1664 return -EINVAL; 1720 1665 } 1721 - 1722 1666 return 0; 1723 1667 } 1724 1668
+6 -4
tools/perf/util/dso.h
··· 160 160 __DSO_LOAD_ERRNO__END, 161 161 }; 162 162 163 - #define DSO__SWAP(dso, type, val) \ 163 + #define DSO_SWAP_TYPE__SWAP(swap_type, type, val) \ 164 164 ({ \ 165 165 type ____r = val; \ 166 - enum dso_swap_type ___dst = dso__needs_swap(dso); \ 167 - BUG_ON(___dst == DSO_SWAP__UNSET); \ 168 - if (___dst == DSO_SWAP__YES) { \ 166 + BUG_ON(swap_type == DSO_SWAP__UNSET); \ 167 + if (swap_type == DSO_SWAP__YES) { \ 169 168 switch (sizeof(____r)) { \ 170 169 case 2: \ 171 170 ____r = bswap_16(val); \ ··· 181 182 } \ 182 183 ____r; \ 183 184 }) 185 + 186 + #define DSO__SWAP(dso, type, val) DSO_SWAP_TYPE__SWAP(dso__needs_swap(dso), type, val) 184 187 185 188 #define DSO__DATA_CACHE_SIZE 4096 186 189 #define DSO__DATA_CACHE_MASK ~(DSO__DATA_CACHE_SIZE - 1) ··· 866 865 off_t dso__data_size(struct dso *dso, struct machine *machine); 867 866 ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, 868 867 u64 offset, u8 *data, ssize_t size); 868 + uint16_t dso__read_e_machine(struct dso *optional_dso, int fd); 869 869 uint16_t dso__e_machine(struct dso *dso, struct machine *machine); 870 870 ssize_t dso__data_read_addr(struct dso *dso, struct map *map, 871 871 struct machine *machine, u64 addr,
+1 -4
tools/perf/util/thread.c
··· 458 458 snprintf(path, sizeof(path), "/proc/%d/exe", pid); 459 459 fd = open(path, O_RDONLY); 460 460 if (fd >= 0) { 461 - _Static_assert(offsetof(Elf32_Ehdr, e_machine) == 18, "Unexpected offset"); 462 - _Static_assert(offsetof(Elf64_Ehdr, e_machine) == 18, "Unexpected offset"); 463 - if (pread(fd, &e_machine, sizeof(e_machine), 18) != sizeof(e_machine)) 464 - e_machine = EM_NONE; 461 + e_machine = dso__read_e_machine(/*optional_dso=*/NULL, fd); 465 462 close(fd); 466 463 } 467 464 return e_machine;