Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 182369
b: refs/heads/master
c: 9e20144
h: refs/heads/master
i:
  182367: ea8b6cb
v: v3
  • Loading branch information
Arnaldo Carvalho de Melo authored and Ingo Molnar committed Jan 16, 2010
1 parent 07d6ce8 commit ec11e92
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 21 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8d0591f6ad9edf66697ce29de176fb6f3213b9e3
refs/heads/master: 9e201442de7c954f03710ac76f28c1927d07550c
2 changes: 1 addition & 1 deletion trunk/tools/perf/util/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ int event__synthesize_kernel_mmap(event__handler_t process,
*/
struct process_symbol_args args = { .name = symbol_name, };

if (kallsyms__parse(&args, find_symbol_cb) <= 0)
if (kallsyms__parse("/proc/kallsyms", &args, find_symbol_cb) <= 0)
return -ENOENT;

size = snprintf(ev.mmap.filename, sizeof(ev.mmap.filename),
Expand Down
15 changes: 11 additions & 4 deletions trunk/tools/perf/util/header.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,21 +237,28 @@ static int dso__cache_build_id(struct dso *self, const char *debugdir)
char *filename = malloc(size),
*linkname = malloc(size), *targetname, *sbuild_id;
int len, err = -1;
bool is_kallsyms = self->kernel && self->long_name[0] != '/';

if (filename == NULL || linkname == NULL)
goto out_free;

len = snprintf(filename, size, "%s%s", debugdir, self->long_name);
len = snprintf(filename, size, "%s%s%s",
debugdir, is_kallsyms ? "/" : "", self->long_name);
if (mkdir_p(filename, 0755))
goto out_free;

len += snprintf(filename + len, sizeof(filename) - len, "/");
sbuild_id = filename + len;
build_id__sprintf(self->build_id, sizeof(self->build_id), sbuild_id);

if (access(filename, F_OK) && link(self->long_name, filename) &&
copyfile(self->long_name, filename))
goto out_free;
if (access(filename, F_OK)) {
if (is_kallsyms) {
if (copyfile("/proc/kallsyms", filename))
goto out_free;
} else if (link(self->long_name, filename) &&
copyfile(self->long_name, filename))
goto out_free;
}

len = snprintf(linkname, size, "%s/.build-id/%.2s",
debugdir, sbuild_id);
Expand Down
48 changes: 35 additions & 13 deletions trunk/tools/perf/util/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,13 +383,14 @@ size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp)
return ret;
}

int kallsyms__parse(void *arg, int (*process_symbol)(void *arg, const char *name,
int kallsyms__parse(const char *filename, void *arg,
int (*process_symbol)(void *arg, const char *name,
char type, u64 start))
{
char *line = NULL;
size_t n;
int err = 0;
FILE *file = fopen("/proc/kallsyms", "r");
FILE *file = fopen(filename, "r");

if (file == NULL)
goto out_failure;
Expand Down Expand Up @@ -466,10 +467,11 @@ static int map__process_kallsym_symbol(void *arg, const char *name,
* so that we can in the next step set the symbol ->end address and then
* call kernel_maps__split_kallsyms.
*/
static int dso__load_all_kallsyms(struct dso *self, struct map *map)
static int dso__load_all_kallsyms(struct dso *self, const char *filename,
struct map *map)
{
struct process_kallsyms_args args = { .map = map, .dso = self, };
return kallsyms__parse(&args, map__process_kallsym_symbol);
return kallsyms__parse(filename, &args, map__process_kallsym_symbol);
}

/*
Expand Down Expand Up @@ -556,10 +558,10 @@ discard_symbol: rb_erase(&pos->rb_node, root);
}


static int dso__load_kallsyms(struct dso *self, struct map *map,
static int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map,
struct perf_session *session, symbol_filter_t filter)
{
if (dso__load_all_kallsyms(self, map) < 0)
if (dso__load_all_kallsyms(self, filename, map) < 0)
return -1;

symbols__fixup_end(&self->symbols[map->type]);
Expand Down Expand Up @@ -1580,7 +1582,8 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
struct perf_session *session, symbol_filter_t filter)
{
int err;
bool is_kallsyms;
const char *kallsyms_filename = NULL;
char *kallsyms_allocated_filename = NULL;

if (vmlinux_path != NULL) {
int i;
Expand All @@ -1606,19 +1609,37 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
*/
if (self->has_build_id) {
u8 kallsyms_build_id[BUILD_ID_SIZE];
char sbuild_id[BUILD_ID_SIZE * 2 + 1];

if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
sizeof(kallsyms_build_id)) == 0) {
is_kallsyms = dso__build_id_equal(self, kallsyms_build_id);
if (is_kallsyms)
if (dso__build_id_equal(self, kallsyms_build_id)) {
kallsyms_filename = "/proc/kallsyms";
goto do_kallsyms;
}
}

build_id__sprintf(self->build_id, sizeof(self->build_id),
sbuild_id);

if (asprintf(&kallsyms_allocated_filename,
"%s/.debug/[kernel.kallsyms]/%s",
getenv("HOME"), sbuild_id) != -1) {
if (access(kallsyms_filename, F_OK)) {
kallsyms_filename = kallsyms_allocated_filename;
goto do_kallsyms;
}
free(kallsyms_allocated_filename);
kallsyms_allocated_filename = NULL;
}

goto do_vmlinux;
}

is_kallsyms = self->long_name[0] == '[';
if (is_kallsyms)
if (self->long_name[0] == '[') {
kallsyms_filename = "/proc/kallsyms";
goto do_kallsyms;
}

do_vmlinux:
err = dso__load_vmlinux(self, map, session, self->long_name, filter);
Expand All @@ -1629,9 +1650,10 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
pr_info("The file %s cannot be used, "
"trying to use /proc/kallsyms...", self->long_name);
do_kallsyms:
err = dso__load_kallsyms(self, map, session, filter);
if (err > 0 && !is_kallsyms)
err = dso__load_kallsyms(self, kallsyms_filename, map, session, filter);
if (err > 0 && kallsyms_filename == NULL)
dso__set_long_name(self, strdup("[kernel.kallsyms]"));
free(kallsyms_allocated_filename);
}

if (err > 0) {
Expand Down
5 changes: 3 additions & 2 deletions trunk/tools/perf/util/symbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,9 @@ int filename__read_build_id(const char *filename, void *bf, size_t size);
int sysfs__read_build_id(const char *filename, void *bf, size_t size);
bool dsos__read_build_ids(void);
int build_id__sprintf(u8 *self, int len, char *bf);
int kallsyms__parse(void *arg, int (*process_symbol)(void *arg, const char *name,
char type, u64 start));
int kallsyms__parse(const char *filename, void *arg,
int (*process_symbol)(void *arg, const char *name,
char type, u64 start));

int symbol__init(void);
bool symbol_type__is_a(char symbol_type, enum map_type map_type);
Expand Down
30 changes: 30 additions & 0 deletions trunk/tools/perf/util/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,33 @@ int mkdir_p(char *path, mode_t mode)
return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0;
}

static int slow_copyfile(const char *from, const char *to)
{
int err = 0;
char *line = NULL;
size_t n;
FILE *from_fp = fopen(from, "r"), *to_fp;

if (from_fp == NULL)
goto out;

to_fp = fopen(to, "w");
if (to_fp == NULL)
goto out_fclose_from;

while (getline(&line, &n, from_fp) > 0)
if (fputs(line, to_fp) == EOF)
goto out_fclose_to;
err = 0;
out_fclose_to:
fclose(to_fp);
free(line);
out_fclose_from:
fclose(from_fp);
out:
return err;
}

int copyfile(const char *from, const char *to)
{
int fromfd, tofd;
Expand All @@ -42,6 +69,9 @@ int copyfile(const char *from, const char *to)
if (stat(from, &st))
goto out;

if (st.st_size == 0) /* /proc? do it slowly... */
return slow_copyfile(from, to);

fromfd = open(from, O_RDONLY);
if (fromfd < 0)
goto out;
Expand Down

0 comments on commit ec11e92

Please sign in to comment.