Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F160328053
D39625.id120501.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D39625.id120501.diff
View Options
diff --git a/lib/libpmcstat/libpmcstat_image.c b/lib/libpmcstat/libpmcstat_image.c
--- a/lib/libpmcstat/libpmcstat_image.c
+++ b/lib/libpmcstat/libpmcstat_image.c
@@ -292,6 +292,94 @@
return;
}
+static Elf *
+pmcstat_image_open_elf(struct pmcstat_image *image,
+ struct pmcstat_args *args, const char *path, int fd,
+ GElf_Ehdr *peh)
+{
+ Elf *e;
+ GElf_Ehdr eh;
+
+ if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
+ warnx("WARNING: Cannot read \"%s\".",
+ path);
+ goto error;
+ }
+
+ if (elf_kind(e) != ELF_K_ELF) {
+ if (args->pa_verbosity >= 2)
+ warnx("WARNING: Cannot determine the type of \"%s\".",
+ path);
+ goto error;
+ }
+
+ if (gelf_getehdr(e, &eh) != &eh) {
+ warnx(
+ "WARNING: Cannot retrieve the ELF Header for \"%s\": %s.",
+ path, elf_errmsg(-1));
+ goto error;
+ }
+
+ if (eh.e_type != ET_EXEC && eh.e_type != ET_DYN &&
+ !(image->pi_iskernelmodule && eh.e_type == ET_REL)) {
+ warnx("WARNING: \"%s\" is of an unsupported ELF type.",
+ path);
+ goto error;
+ }
+
+ if (peh != NULL)
+ *peh = eh;
+ return (e);
+
+error:
+ if (e != NULL)
+ (void) elf_end(e);
+ return (NULL);
+}
+
+static bool
+pmcstat_image_scan_elf_sections(struct pmcstat_image *image,
+ const char *path, Elf *e, uintptr_t *pminva, uintptr_t *pmaxva)
+{
+ size_t i, nsh;
+ uintptr_t minva, maxva;
+ Elf_Scn *scn;
+ GElf_Shdr sh;
+
+ if (elf_getshnum(e, &nsh) == 0) {
+ warnx(
+"WARNING: Could not determine the number of sections for \"%s\": %s.",
+ path, elf_errmsg(-1));
+ goto error;
+ }
+
+ for (i = 0; i < nsh; i++) {
+ if ((scn = elf_getscn(e, i)) == NULL ||
+ gelf_getshdr(scn, &sh) != &sh) {
+ warnx(
+"WARNING: Could not retrieve section header #%ju in \"%s\": %s.",
+ (uintmax_t) i, path, elf_errmsg(-1));
+ goto error;
+ }
+ if (sh.sh_flags & SHF_EXECINSTR) {
+ minva = min(minva, sh.sh_addr);
+ maxva = max(maxva, sh.sh_addr + sh.sh_size);
+ }
+ if (sh.sh_type == SHT_SYMTAB || sh.sh_type == SHT_DYNSYM)
+ pmcstat_image_add_symbols(image, e, scn, &sh);
+ }
+
+ if (pminva != NULL)
+ *pminva = minva;
+ if (pmaxva != NULL)
+ *pmaxva = maxva;
+
+ return (true);
+
+error:
+ return (false);
+}
+
/*
* Examine an ELF file to determine the size of its text segment.
* Sets image->pi_type if anything conclusive can be determined about
@@ -303,19 +391,18 @@
struct pmcstat_args *args)
{
int fd;
- size_t i, nph, nsh;
+ size_t i, nph;
const char *path, *elfbase;
char *p, *endp;
bool first_exec_segment;
- uintfptr_t minva, maxva;
+ uintptr_t minva, maxva;
Elf *e;
- Elf_Scn *scn;
GElf_Ehdr eh;
GElf_Phdr ph;
- GElf_Shdr sh;
enum pmcstat_image_type image_type;
char buffer[PATH_MAX];
char buffer_modules[PATH_MAX];
+ char *chosen_buffer;
assert(image->pi_type == PMCSTAT_IMAGE_UNKNOWN);
@@ -345,13 +432,15 @@
}
e = NULL;
- fd = open(buffer, O_RDONLY, 0);
- if (fd < 0 && !image->pi_iskernelmodule) {
+ if ((fd = open(buffer, O_RDONLY, 0)) >= 0) {
+ chosen_buffer = buffer;
+ } else if (!image->pi_iskernelmodule) {
warnx("WARNING: Cannot open \"%s\".",
buffer);
goto done;
- }
- if (fd < 0 && (fd = open(buffer_modules, O_RDONLY, 0)) < 0) {
+ } else if ((fd = open(buffer_modules, O_RDONLY, 0)) >= 0) {
+ chosen_buffer = buffer_modules;
+ } else {
warnx("WARNING: Cannot open \"%s\" or \"%s\".",
buffer, buffer_modules);
goto done;
@@ -361,32 +450,9 @@
goto done;
}
- if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
- warnx("WARNING: Cannot read \"%s\".",
- buffer);
- goto done;
- }
-
- if (elf_kind(e) != ELF_K_ELF) {
- if (args->pa_verbosity >= 2)
- warnx("WARNING: Cannot determine the type of \"%s\".",
- buffer);
- goto done;
- }
-
- if (gelf_getehdr(e, &eh) != &eh) {
- warnx(
- "WARNING: Cannot retrieve the ELF Header for \"%s\": %s.",
- buffer, elf_errmsg(-1));
- goto done;
- }
-
- if (eh.e_type != ET_EXEC && eh.e_type != ET_DYN &&
- !(image->pi_iskernelmodule && eh.e_type == ET_REL)) {
- warnx("WARNING: \"%s\" is of an unsupported ELF type.",
- buffer);
+ e = pmcstat_image_open_elf(image, args, chosen_buffer, fd, &eh);
+ if (e == NULL)
goto done;
- }
image_type = eh.e_ident[EI_CLASS] == ELFCLASS32 ?
PMCSTAT_IMAGE_ELF32 : PMCSTAT_IMAGE_ELF64;
@@ -400,7 +466,7 @@
if (elf_getphnum(e, &nph) == 0) {
warnx(
"WARNING: Could not determine the number of program headers in \"%s\": %s.",
- buffer,
+ chosen_buffer,
elf_errmsg(-1));
goto done;
}
@@ -409,7 +475,8 @@
if (gelf_getphdr(e, i, &ph) != &ph) {
warnx(
"WARNING: Retrieval of PHDR entry #%ju in \"%s\" failed: %s.",
- (uintmax_t) i, buffer, elf_errmsg(-1));
+ (uintmax_t) i, chosen_buffer,
+ elf_errmsg(-1));
goto done;
}
switch (ph.p_type) {
@@ -420,7 +487,7 @@
if ((elfbase = elf_rawfile(e, NULL)) == NULL) {
warnx(
"WARNING: Cannot retrieve the interpreter for \"%s\": %s.",
- buffer, elf_errmsg(-1));
+ chosen_buffer, elf_errmsg(-1));
goto done;
}
image->pi_dynlinkerpath =
@@ -439,30 +506,12 @@
}
/*
- * Get the min and max VA associated with this ELF object.
+ * Get the min and max VA associated with this ELF object and add
+ * symbol information.
*/
- if (elf_getshnum(e, &nsh) == 0) {
- warnx(
-"WARNING: Could not determine the number of sections for \"%s\": %s.",
- buffer, elf_errmsg(-1));
+ if (!pmcstat_image_scan_elf_sections(image, chosen_buffer, e,
+ &minva, &maxva))
goto done;
- }
-
- for (i = 0; i < nsh; i++) {
- if ((scn = elf_getscn(e, i)) == NULL ||
- gelf_getshdr(scn, &sh) != &sh) {
- warnx(
-"WARNING: Could not retrieve section header #%ju in \"%s\": %s.",
- (uintmax_t) i, buffer, elf_errmsg(-1));
- goto done;
- }
- if (sh.sh_flags & SHF_EXECINSTR) {
- minva = min(minva, sh.sh_addr);
- maxva = max(maxva, sh.sh_addr + sh.sh_size);
- }
- if (sh.sh_type == SHT_SYMTAB || sh.sh_type == SHT_DYNSYM)
- pmcstat_image_add_symbols(image, e, scn, &sh);
- }
image->pi_start = minva;
image->pi_end = maxva;
@@ -471,13 +520,13 @@
/* Build display name
*/
- endp = buffer;
- for (p = buffer; *p; p++)
+ endp = chosen_buffer;
+ for (p = chosen_buffer; *p; p++)
if (*p == '/')
endp = p+1;
image->pi_name = pmcstat_string_intern(endp);
- done:
+done:
(void) elf_end(e);
if (fd >= 0)
(void) close(fd);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Jun 24, 8:07 AM (30 m, 1 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34278076
Default Alt Text
D39625.id120501.diff (6 KB)
Attached To
Mode
D39625: libpmcstat: Extract parts of pmcstat_image_get_elf_params
Attached
Detach File
Event Timeline
Log In to Comment