aboutsummaryrefslogtreecommitdiff
path: root/gold/output.h
diff options
context:
space:
mode:
Diffstat (limited to 'gold/output.h')
-rw-r--r--gold/output.h225
1 files changed, 210 insertions, 15 deletions
diff --git a/gold/output.h b/gold/output.h
index 377864c..bc10950 100644
--- a/gold/output.h
+++ b/gold/output.h
@@ -38,6 +38,7 @@ class General_options;
class Object;
class Symbol;
class Output_file;
+class Output_merge_base;
class Output_section;
class Relocatable_relocs;
class Target;
@@ -46,6 +47,71 @@ class Sized_target;
template<int size, bool big_endian>
class Sized_relobj;
+// This class specifies an input section. It is used as a key type
+// for maps.
+
+class Input_section_specifier
+{
+ public:
+ Input_section_specifier(const Relobj* relobj, unsigned int shndx)
+ : relobj_(relobj), shndx_(shndx)
+ { }
+
+ // Return Relobj of this.
+ const Relobj*
+ relobj() const
+ { return this->relobj_; }
+
+ // Return section index of this.
+ unsigned int
+ shndx() const
+ { return this->shndx_; }
+
+ // Whether this equals to another specifier ISS.
+ bool
+ eq(const Input_section_specifier& iss) const
+ { return this->relobj_ == iss.relobj_ && this->shndx_ == iss.shndx_; }
+
+ // Compute a hash value of this.
+ size_t
+ hash_value() const
+ { return this->string_hash(this->relobj_->name().c_str()) ^ this->shndx_; }
+
+ // Functors for containers.
+ struct equal_to
+ {
+ bool
+ operator()(const Input_section_specifier& iss1,
+ const Input_section_specifier& iss2) const
+ { return iss1.eq(iss2); }
+ };
+
+ struct hash
+ {
+ size_t
+ operator()(const Input_section_specifier& iss) const
+ { return iss.hash_value(); }
+ };
+
+ private:
+ // For portability, we use our own string hash function instead of assuming
+ // __gnu_cxx::hash or std::tr1::hash is available. This is the same hash
+ // function used in Stringpool_template::string_hash.
+ static size_t
+ string_hash(const char* s)
+ {
+ size_t h = 5381;
+ while (*s != '\0')
+ h = h * 33 + *s++;
+ return h;
+ }
+
+ // An object.
+ const Relobj* relobj_;
+ // A section index.
+ unsigned int shndx_;
+};
+
// An abtract class for data which has to go into the output file.
class Output_data
@@ -1987,7 +2053,7 @@ class Output_symtab_xindex : public Output_section_data
};
// A relaxed input section.
-class Output_relaxed_input_section : public Output_section_data
+class Output_relaxed_input_section : public Output_section_data_build
{
public:
// We would like to call relobj->section_addralign(shndx) to get the
@@ -1995,7 +2061,7 @@ class Output_relaxed_input_section : public Output_section_data
// are repsonsible for ensuring that.
Output_relaxed_input_section(Relobj* relobj, unsigned int shndx,
uint64_t addralign)
- : Output_section_data(addralign), relobj_(relobj), shndx_(shndx)
+ : Output_section_data_build(addralign), relobj_(relobj), shndx_(shndx)
{ }
// Return the Relobj of this relaxed input section.
@@ -2041,6 +2107,10 @@ class Output_section : public Output_data
void
add_output_section_data(Output_section_data* posd);
+ // Add a relaxed input section PORIS to this output section.
+ void
+ add_relaxed_input_section(Output_relaxed_input_section* poris);
+
// Return the section name.
const char*
name() const
@@ -2510,6 +2580,11 @@ class Output_section : public Output_data
void
restore_states();
+ // Convert existing input sections to relaxed input sections.
+ void
+ convert_input_sections_to_relaxed_sections(
+ const std::vector<Output_relaxed_input_section*>& sections);
+
// Print merge statistics to stderr.
void
print_merge_stats();
@@ -2625,7 +2700,6 @@ class Output_section : public Output_data
void
write_to_postprocessing_buffer();
- private:
// In some cases we need to keep a list of the input sections
// associated with this output section. We only need the list if we
// might have to change the offsets of the input section within the
@@ -2741,16 +2815,24 @@ class Output_section : public Output_data
Relobj*
relobj() const
{
- gold_assert(this->is_input_section());
- return this->u2_.object;
+ if (this->is_input_section())
+ return this->u2_.object;
+ else if (this->is_relaxed_input_section())
+ return this->u2_.poris->relobj();
+ else
+ gold_unreachable();
}
// Return the input section index for an input section.
unsigned int
shndx() const
{
- gold_assert(this->is_input_section());
- return this->shndx_;
+ if (this->is_input_section())
+ return this->shndx_;
+ else if (this->is_relaxed_input_section())
+ return this->u2_.poris->shndx();
+ else
+ gold_unreachable();
}
// For non-input-sections, return the associated Output_section_data
@@ -2891,6 +2973,12 @@ class Output_section : public Output_data
typedef std::vector<Input_section> Input_section_list;
+ // Allow a child class to access the input sections.
+ const Input_section_list&
+ input_sections() const
+ { return this->input_sections_; }
+
+ private:
// We only save enough information to undo the effects of section layout.
class Checkpoint_output_section
{
@@ -2921,9 +3009,9 @@ class Output_section : public Output_data
{ return this->flags_; }
// Return a reference to the input section list copy.
- const Input_section_list&
- input_sections() const
- { return this->input_sections_copy_; }
+ Input_section_list*
+ input_sections()
+ { return &this->input_sections_copy_; }
// Return the size of input_sections at the time when checkpoint is
// taken.
@@ -2974,7 +3062,6 @@ class Output_section : public Output_data
bool attached_input_sections_are_sorted_;
};
- private:
// This class is used to sort the input sections.
class Input_section_sort_entry;
@@ -3018,6 +3105,82 @@ class Output_section : public Output_data
typedef std::vector<Fill> Fill_list;
+ // This class describes properties of merge data sections. It is used
+ // as a key type for maps.
+ class Merge_section_properties
+ {
+ public:
+ Merge_section_properties(bool is_string, uint64_t entsize,
+ uint64_t addralign)
+ : is_string_(is_string), entsize_(entsize), addralign_(addralign)
+ { }
+
+ // Whether this equals to another Merge_section_properties MSP.
+ bool
+ eq(const Merge_section_properties& msp) const
+ {
+ return ((this->is_string_ == msp.is_string_)
+ && (this->entsize_ == msp.entsize_)
+ && (this->addralign_ == msp.addralign_));
+ }
+
+ // Compute a hash value for this using 64-bit FNV-1a hash.
+ size_t
+ hash_value() const
+ {
+ uint64_t h = 14695981039346656037ULL; // FNV offset basis.
+ uint64_t prime = 1099511628211ULL;
+ h = (h ^ static_cast<uint64_t>(this->is_string_)) * prime;
+ h = (h ^ static_cast<uint64_t>(this->entsize_)) * prime;
+ h = (h ^ static_cast<uint64_t>(this->addralign_)) * prime;
+ return h;
+ }
+
+ // Functors for associative containers.
+ struct equal_to
+ {
+ bool
+ operator()(const Merge_section_properties& msp1,
+ const Merge_section_properties& msp2) const
+ { return msp1.eq(msp2); }
+ };
+
+ struct hash
+ {
+ size_t
+ operator()(const Merge_section_properties& msp) const
+ { return msp.hash_value(); }
+ };
+
+ private:
+ // Whether this merge data section is for strings.
+ bool is_string_;
+ // Entsize of this merge data section.
+ uint64_t entsize_;
+ // Address alignment.
+ uint64_t addralign_;
+ };
+
+ // Map that link Merge_section_properties to Output_merge_base.
+ typedef Unordered_map<Merge_section_properties, Output_merge_base*,
+ Merge_section_properties::hash,
+ Merge_section_properties::equal_to>
+ Merge_section_by_properties_map;
+
+ // Map that link Input_section_specifier to Output_section_data.
+ typedef Unordered_map<Input_section_specifier, Output_section_data*,
+ Input_section_specifier::hash,
+ Input_section_specifier::equal_to>
+ Output_section_data_by_input_section_map;
+
+ // Map used during relaxation of existing sections. This map
+ // an input section specifier to an input section list index.
+ // We assume that Input_section_list is a vector.
+ typedef Unordered_map<Input_section_specifier, size_t,
+ Input_section_specifier::hash,
+ Input_section_specifier::equal_to>
+ Relaxation_map;
+
// Add a new output section by Input_section.
void
add_output_section_data(Input_section*);
@@ -3036,14 +3199,34 @@ class Output_section : public Output_data
add_output_merge_section(Output_section_data* posd, bool is_string,
uint64_t entsize);
- // Relax an existing input section.
- void
- relax_input_section(Output_relaxed_input_section*);
-
// Sort the attached input sections.
void
sort_attached_input_sections();
+ // Find the merge section into which an input section with index SHNDX in
+ // OBJECT has been added. Return NULL if none found.
+ Output_section_data*
+ find_merge_section(const Relobj* object, unsigned int shndx) const;
+
+ // Find a relaxed input section to an input section in OBJECT
+ // with index SHNDX. Return NULL if none is found.
+ const Output_section_data*
+ find_relaxed_input_section(const Relobj* object, unsigned int shndx) const;
+
+ // Build a relaxation map.
+ void
+ build_relaxation_map(
+ const Input_section_list& input_sections,
+ size_t limit,
+ Relaxation_map* map) const;
+
+ // Convert input sections in an input section list into relaxed sections.
+ void
+ convert_input_sections_in_list_to_relaxed_sections(
+ const std::vector<Output_relaxed_input_section*>& relaxed_sections,
+ const Relaxation_map& map,
+ Input_section_list* input_sections);
+
// Most of these fields are only valid after layout.
// The name of the section. This will point into a Stringpool.
@@ -3149,6 +3332,18 @@ class Output_section : public Output_data
uint64_t tls_offset_;
// Saved checkpoint.
Checkpoint_output_section* checkpoint_;
+ // Map from input sections to merge sections.
+ Output_section_data_by_input_section_map merge_section_map_;
+ // Map from merge section properties to merge_sections;
+ Merge_section_by_properties_map merge_section_by_properties_map_;
+ // Map from input sections to relaxed input sections. This is mutable
+ // beacause it is udpated lazily. We may need to update it in a
+ // const qualified method.
+ mutable Output_section_data_by_input_section_map relaxed_input_section_map_;
+ // Whether relaxed_input_section_map_ is valid.
+ mutable bool is_relaxed_input_section_map_valid_;
+ // Whether code-fills are generated at write.
+ bool generate_code_fills_at_write_;
};
// An output segment. PT_LOAD segments are built from collections of