summaryrefslogtreecommitdiffstats
path: root/src/build/linker
diff options
context:
space:
mode:
Diffstat (limited to 'src/build/linker')
-rw-r--r--src/build/linker/genlist.C71
-rw-r--r--src/build/linker/linker.C30
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) &&
OpenPOWER on IntegriCloud