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     /* Checking nbfd isn't really necessary, except to silence
00043      * compile warning.  In fact, nbfd will always be non-NULL.
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     /* Checking nbfd isn't really necessary, except to silence
00059      * compile warning.  In fact, nbfd will always be non-NULL.
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     /* Checking abfd isn't really necessary, except to silence
00076      * compile warning.  In fact, abfd will always be non-NULL.
00077      */
00078     if (abfd)
00079         return nbytes;
00080     else
00081         return 0;
00082 }
00083 } // namespace anon
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 }

Generated on 8 Nov 2012 for Oprofile by  doxygen 1.6.1