bfd_spu_support.cpp
Go to the documentation of this file.00001
00012 #include "bfd_support.h"
00013 #include "op_bfd.h"
00014 #include "config.h"
00015 #include "cverb.h"
00016
00017 #include <stdlib.h>
00018 #include <stdio.h>
00019 #include <iostream>
00020 #include <fstream>
00021 #include <sstream>
00022 #include <string>
00023 #include <cstring>
00024 #include <sys/types.h>
00025
00026 struct spu_elf {
00027 FILE * stream;
00028 off_t spu_offset;
00029 };
00030
00031 using namespace std;
00032
00033 extern verbose vbfd;
00034
00035 #ifdef HAVE_BFD_OPENR_IOVEC_WITH_7PARMS
00036
00037 namespace {
00038
00039 static void *
00040 spu_bfd_iovec_open(bfd * nbfd, void * open_closure)
00041 {
00042
00043
00044
00045 if (nbfd)
00046 return open_closure;
00047 else
00048 return NULL;
00049 }
00050
00051 static int
00052 spu_bfd_iovec_close(bfd * nbfd, void * stream)
00053 {
00054 spu_elf * my_stream = (spu_elf *) stream;
00055
00056 fclose(my_stream->stream);
00057 free(my_stream);
00058
00059
00060
00061 if (nbfd)
00062 return 1;
00063 else
00064 return 0;
00065 }
00066
00067 static file_ptr
00068 spu_bfd_iovec_pread(bfd * abfd, void * stream, void * buf,
00069 file_ptr nbytes, file_ptr offset)
00070 {
00071 spu_elf * my_stream = (spu_elf *) stream;
00072 fseek(my_stream->stream, my_stream->spu_offset + offset,
00073 SEEK_SET);
00074 nbytes = fread(buf, sizeof(char), nbytes, my_stream->stream);
00075
00076
00077
00078 if (abfd)
00079 return nbytes;
00080 else
00081 return 0;
00082 }
00083 }
00084 #endif
00085
00086 bfd *
00087 spu_open_bfd(string const name, int fd, uint64_t offset_to_spu_elf)
00088 {
00089
00090 bfd * nbfd = NULL;
00091 spu_elf * spu_elf_stream = (spu_elf *)malloc(sizeof(spu_elf));
00092
00093 FILE * fp = fdopen(fd, "r");
00094 spu_elf_stream->stream = fp;
00095 spu_elf_stream->spu_offset = offset_to_spu_elf;
00096 #ifdef HAVE_BFD_OPENR_IOVEC_WITH_7PARMS
00097 nbfd = bfd_openr_iovec(strdup(name.c_str()), "elf32-spu",
00098 spu_bfd_iovec_open, spu_elf_stream,
00099 spu_bfd_iovec_pread, spu_bfd_iovec_close, NULL);
00100 #else
00101 ostringstream os;
00102 os << "Attempt to process a Cell Broadband Engine SPU profile without"
00103 << "proper BFD support.\n"
00104 << "Rebuild the opreport utility with the correct BFD library.\n"
00105 << "See the OProfile user manual for more information.\n";
00106 throw op_runtime_error(os.str());
00107 #endif
00108 if (!nbfd) {
00109 cverb << vbfd << "spu_open_bfd failed for " << name << endl;
00110 return NULL;
00111 }
00112
00113 bfd_check_format(nbfd, bfd_object);
00114
00115 return nbfd;
00116 }