blob: 7df1488dabc103cba1d2ba5b0516e73cb575e4c7 [file] [log] [blame]
Apply basic patch by David Blaikie to update gold dwp tool to handle
DWARF v5. This is the second of three patches for DWARF v5.
This has some memory efficiency improvements.
This patch created for Chrome OS by Caroline Tice.
Date: 20-Nov-2020
diff --git a/gold/dwp.cc b/gold/dwp.cc
index 5501985c..60de58bc 100644
--- a/gold/dwp.cc
+++ b/gold/dwp.cc
@@ -32,7 +32,7 @@
#include <vector>
#include <algorithm>
-#include <functional>
+#include <memory>
#include "getopt.h"
#include "libiberty.h"
@@ -633,6 +633,11 @@ class Dwp_output_file
unsigned int
add_output_section(const char* section_name, int align);
+ // Prepare to write a new section to the output file.
+ off_t
+ start_new_section(const char* section_name, section_size_type len,
+ int align);
+
// Write a new section to the output file.
void
write_new_section(const char* section_name, const unsigned char* contents,
@@ -1565,8 +1570,6 @@ Dwo_file::add_strings(Dwp_output_file* output_file, unsigned int debug_str)
}
new_offset = 0;
this->str_offset_map_.push_back(std::make_pair(i, new_offset));
- if (is_new)
- delete[] pdata;
}
// Copy a section from the input file to the output file.
@@ -1781,7 +1784,7 @@ section_offset_type
Dwp_output_file::add_string(const char* str, size_t len)
{
Stringpool::Key key;
- this->stringpool_.add_with_length(str, len, true, &key);
+ this->stringpool_.add_with_length(str, len, false, &key);
this->have_strings_ = true;
// We aren't supposed to call get_offset() until after
// calling set_string_offsets(), but the offsets will
@@ -2053,10 +2056,10 @@ Dwp_output_file::finalize()
{
this->stringpool_.set_string_offsets();
section_size_type len = this->stringpool_.get_strtab_size();
- buf = new unsigned char[len];
- this->stringpool_.write_to_buffer(buf, len);
- this->write_new_section(".debug_str.dwo", buf, len, 1);
- delete[] buf;
+ off_t file_offset = this->start_new_section(".debug_str.dwo", len, 1);
+ this->stringpool_.write_to_file(this->fd_, file_offset,
+ this->name_, ".debug_str.dwo");
+ this->next_file_offset_ = file_offset + len;
}
// Write the CU and TU indexes.
@@ -2138,11 +2141,10 @@ Dwp_output_file::write_contributions(const Section& sect)
}
}
-// Write a new section to the output file.
+// Prepare to write a new section to the output file.
-void
-Dwp_output_file::write_new_section(const char* section_name,
- const unsigned char* contents,
+off_t
+Dwp_output_file::start_new_section(const char* section_name,
section_size_type len, int align)
{
section_name = this->shstrtab_.add_with_length(section_name,
@@ -2155,7 +2157,18 @@ Dwp_output_file::write_new_section(const char* section_name,
section.offset = file_offset;
section.size = len;
::fseek(this->fd_, file_offset, SEEK_SET);
- if (::fwrite(contents, 1, len, this->fd_) < len)
+ return file_offset;
+}
+
+// Write a new section to the output file.
+
+void
+Dwp_output_file::write_new_section(const char* section_name,
+ const unsigned char* contents,
+ section_size_type len, int align)
+{
+ off_t file_offset = this->start_new_section(section_name, len, align);
+ if (::fwrite(contents, 1, len, this->fd_) < len)
gold_fatal(_("%s: error writing section '%s'"), this->name_, section_name);
this->next_file_offset_ = file_offset + len;
}
@@ -2680,14 +2693,25 @@ main(int argc, char** argv)
// Process each file, adding its contents to the output file.
Dwp_output_file output_file(output_filename.c_str());
+ std::vector<Dwo_file*> dwo_files;
for (File_list::const_iterator f = files.begin(); f != files.end(); ++f)
{
if (verbose)
fprintf(stderr, "%s\n", f->dwo_name.c_str());
- Dwo_file dwo_file(f->dwo_name.c_str());
- dwo_file.read(&output_file);
+ Dwo_file* dwo_file = new Dwo_file(f->dwo_name.c_str());
+ dwo_file->read(&output_file);
+ dwo_files.push_back(dwo_file);
}
output_file.finalize();
+ // Clean up dwo_files.
+ for (std::vector<Dwo_file*>::iterator i = dwo_files.begin(),
+ e = dwo_files.end();
+ i != e;
+ ++i)
+ {
+ delete *i;
+ }
+
return EXIT_SUCCESS;
}
diff --git a/gold/stringpool.h b/gold/stringpool.h
index b7ac54f5..3288772a 100644
--- a/gold/stringpool.h
+++ b/gold/stringpool.h
@@ -285,6 +285,12 @@ class Stringpool_template
void
write_to_buffer(unsigned char* buffer, section_size_type buffer_size);
+ // Write the string table into the specified file at the specified
+ // offset.
+ void
+ write_to_file(FILE *fd, off_t file_offset, const char *name,
+ const char *section_name);
+
// Dump statistical information to stderr.
void
print_stats(const char*) const;
diff --git a/gold/stringpool.cc b/gold/stringpool.cc
index 8d438a4e..b8565c0b 100644
--- a/gold/stringpool.cc
+++ b/gold/stringpool.cc
@@ -491,6 +491,38 @@ Stringpool_template<Stringpool_char>::write_to_buffer(
}
}
+// Write the ELF strtab into the file at the specified offset.
+
+template<typename Stringpool_char>
+void
+Stringpool_template<Stringpool_char>::write_to_file(
+ FILE* fd, off_t file_offset,
+ const char* name, const char* section_name)
+{
+ gold_assert(fd != NULL);
+ gold_assert(this->strtab_size_ != 0);
+ if (this->zero_null_)
+ {
+ char buf[] = {'\0'};
+ ::fseek(fd, file_offset, SEEK_SET);
+ if (::fwrite(buf, 1, 1, fd) < 1)
+ gold_fatal(_("%s: error writing section '%s'"), name, section_name);
+ }
+
+ for (typename String_set_type::const_iterator p = this->string_set_.begin();
+ p != this->string_set_.end();
+ ++p)
+ {
+ const unsigned int len = (p->first.length + 1) * sizeof(Stringpool_char);
+ const section_offset_type offset = this->key_to_offset_[p->second - 1];
+ gold_assert(static_cast<section_size_type>(offset) + len
+ <= this->strtab_size_);
+ ::fseek(fd, file_offset + offset, SEEK_SET);
+ if (::fwrite(p->first.string, 1, len, fd) < len)
+ gold_fatal(_("%s: error writing section '%s'"), name, section_name);
+ }
+}
+
// Write the ELF strtab into the output file at the specified offset.
template<typename Stringpool_char>