diff options
Diffstat (limited to 'src/build/linker')
-rw-r--r-- | src/build/linker/genlist.C | 71 | ||||
-rw-r--r-- | src/build/linker/linker.C | 30 |
2 files changed, 87 insertions, 14 deletions
diff --git a/src/build/linker/genlist.C b/src/build/linker/genlist.C index 053f7aaa2..d89fbfaa6 100644 --- a/src/build/linker/genlist.C +++ b/src/build/linker/genlist.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2015 */ +/* Contributors Listed Below - COPYRIGHT 2013,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -95,6 +95,19 @@ string g_imageName; * call binutils tools. */ char* g_crossPrefix = NULL; + /** Whether we should use cached objdump files (true) or redump the + ELF objects (false). */ +bool use_cached_objdump = false; + + /** Print status messages */ +bool verbose = false; + +#define VFPRINTF(...) \ + do { \ + if (verbose) \ + fprintf(__VA_ARGS__); \ + } while (0) + int main(int argc, char** argv) { // Only parameter allowed is the name of the base image. @@ -103,6 +116,16 @@ int main(int argc, char** argv) print_usage(); } + verbose = getenv("BUILD_VERBOSE") != NULL; + + use_cached_objdump = getenv("BUILD_FAST") != NULL; + + if (use_cached_objdump) { + VFPRINTF(stderr, "Using cached OBJDUMP output\n"); + } else { + VFPRINTF(stderr, "Using fresh OBJDUMP output\n"); + } + // Get base image name from parameters. g_imageName = argv[1]; add_image_subdir(g_imageName); @@ -310,18 +333,42 @@ void* read_module_content(void* input) // Assumes they are in the same subdirectory. string module_path = g_imageName.substr(0, g_imageName.rfind('/') + 1) + module; + const string objdump_path = + g_imageName.substr(0, g_imageName.rfind('/') + 1) + "/objdump/" + module; + + FILE* pipe = NULL; - // Create the 'objdump' command for finding all the symbols and start as - // a sub-process. - // -d - Disassemble sections containing code. - // -C - Intersparse C code. - // -S - Demangle symbol names. - // -j .text, .data, .rodata - Only dump those 3 sections. - string command = string(g_crossPrefix) + - string("objdump -dCS -j .text -j .data -j .rodata ") + - module_path; - FILE* pipe = popen(command.c_str(), "r"); - if (NULL == pipe) return NULL; + VFPRINTF(stderr, "GENLIST: Processing %s\n", module_path.c_str()); + + if (use_cached_objdump) { + string bzcat_command = "bzcat " + objdump_path + ".objdump"; + pipe = popen(bzcat_command.c_str(), "r"); + + if (NULL == pipe) { + VFPRINTF(stderr, "GENLIST: Failed to run %s, falling back to live dump\n", + bzcat_command.c_str()); + } + } + + if (pipe == NULL) { + // Create the 'objdump' command for finding all the symbols and start as + // a sub-process. + // -d - Disassemble sections containing code. + // -C - Intersparse C code. + // -S - Demangle symbol names. + // -j .text, .data, .rodata - Only dump those 3 sections. + string objdump_command = string(g_crossPrefix) + + string("objdump -dCS -j .text -j .data -j .rodata ") + + module_path; + + pipe = popen(objdump_command.c_str(), "r"); + + if (NULL == pipe) { + fprintf(stderr, "GENLIST: Failed to open pipe for objdump: %s\n", + objdump_command.c_str()); + return NULL; + } + } // Start result string and add module start header. string result; diff --git a/src/build/linker/linker.C b/src/build/linker/linker.C index a9a9d0f5e..6a8854d83 100644 --- a/src/build/linker/linker.C +++ b/src/build/linker/linker.C @@ -112,6 +112,8 @@ struct Section size_t size; bfd_byte* data; + + Section() : name(""), vma_offset(0), size(0), data(NULL) {} }; /** @@ -123,6 +125,7 @@ struct Object string name; //!< full path name of file bfd* image; //!< bfd image of object Section text; //!< text section of binary + Section sfpr; //!< sfpr section of binary Section rodata; //!< rodata section of binary Section data; //!< data section of binary map<string, Symbol> symbols; //!< symbol map @@ -203,7 +206,7 @@ struct Object /** * CTOR default */ - Object() : image(NULL), text(), rodata(), data(), offset(0), + Object() : image(NULL), text(), rodata(), data(), sfpr(), offset(0), base_addr(0), iv_output(NULL), tls_module(-1) {} @@ -213,7 +216,7 @@ struct Object * @param[in] i_out : output FILE handle */ Object(unsigned long i_baseAddr, FILE* i_out) - : image(NULL), text(), rodata(), data(), offset(0), + : image(NULL), text(), rodata(), data(), sfpr(), offset(0), base_addr(i_baseAddr), iv_output(i_out), tls_module(-1) {} }; @@ -439,6 +442,8 @@ int main(int argc, char** argv) // A contained member value might be something like // _ZZ3fooE3bar. string sym_name = string((i->c_str())+1); + const char* gcovstr = "__gcov"; + size_t gcovstrlen = strlen(gcovstr); cout << "Checking weak symbol: " << *i << endl; @@ -451,6 +456,12 @@ int main(int argc, char** argv) == j->find("traceData_codeInfo")) && (*i != *j)) { + if (strncmp((*j).c_str(), + gcovstr, + gcovstrlen)==0) + { + continue; + } cout << "\tDuplicate member found: " << *j << endl; throw std::runtime_error( string("Duplicate weak symbol with contained " @@ -586,6 +597,11 @@ bool Object::read_object(const char* i_file) { s = &this->text; } + else if (string(".sfpr") == + bfd_get_section_name(image, image_section)) + { + s = &this->sfpr; + } else if (string(".rodata") == bfd_get_section_name(image, image_section)) { @@ -640,6 +656,16 @@ bool Object::write_object() cout << strerror(error) << endl; } + // Output sfpr section. + fseek(iv_output, offset + sfpr.vma_offset, SEEK_SET); + if ((0 != sfpr.size) && + (sfpr.size != fwrite(sfpr.data, 1, sfpr.size, iv_output))) + { + int error = errno; + cout << "Error writing to output for sfpr." << endl; + cout << strerror(error) << endl; + } + // Output RODATA section. fseek(iv_output, offset + rodata.vma_offset, SEEK_SET); if ((0 != rodata.size) && |