1*a9fa9459Szrj // output.h -- manage the output file for gold -*- C++ -*- 2*a9fa9459Szrj 3*a9fa9459Szrj // Copyright (C) 2006-2016 Free Software Foundation, Inc. 4*a9fa9459Szrj // Written by Ian Lance Taylor <iant@google.com>. 5*a9fa9459Szrj 6*a9fa9459Szrj // This file is part of gold. 7*a9fa9459Szrj 8*a9fa9459Szrj // This program is free software; you can redistribute it and/or modify 9*a9fa9459Szrj // it under the terms of the GNU General Public License as published by 10*a9fa9459Szrj // the Free Software Foundation; either version 3 of the License, or 11*a9fa9459Szrj // (at your option) any later version. 12*a9fa9459Szrj 13*a9fa9459Szrj // This program is distributed in the hope that it will be useful, 14*a9fa9459Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 15*a9fa9459Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*a9fa9459Szrj // GNU General Public License for more details. 17*a9fa9459Szrj 18*a9fa9459Szrj // You should have received a copy of the GNU General Public License 19*a9fa9459Szrj // along with this program; if not, write to the Free Software 20*a9fa9459Szrj // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21*a9fa9459Szrj // MA 02110-1301, USA. 22*a9fa9459Szrj 23*a9fa9459Szrj #ifndef GOLD_OUTPUT_H 24*a9fa9459Szrj #define GOLD_OUTPUT_H 25*a9fa9459Szrj 26*a9fa9459Szrj #include <algorithm> 27*a9fa9459Szrj #include <list> 28*a9fa9459Szrj #include <vector> 29*a9fa9459Szrj 30*a9fa9459Szrj #include "elfcpp.h" 31*a9fa9459Szrj #include "mapfile.h" 32*a9fa9459Szrj #include "layout.h" 33*a9fa9459Szrj #include "reloc-types.h" 34*a9fa9459Szrj 35*a9fa9459Szrj namespace gold 36*a9fa9459Szrj { 37*a9fa9459Szrj 38*a9fa9459Szrj class General_options; 39*a9fa9459Szrj class Object; 40*a9fa9459Szrj class Symbol; 41*a9fa9459Szrj class Output_merge_base; 42*a9fa9459Szrj class Output_section; 43*a9fa9459Szrj class Relocatable_relocs; 44*a9fa9459Szrj class Target; 45*a9fa9459Szrj template<int size, bool big_endian> 46*a9fa9459Szrj class Sized_target; 47*a9fa9459Szrj template<int size, bool big_endian> 48*a9fa9459Szrj class Sized_relobj; 49*a9fa9459Szrj template<int size, bool big_endian> 50*a9fa9459Szrj class Sized_relobj_file; 51*a9fa9459Szrj 52*a9fa9459Szrj // This class represents the output file. 53*a9fa9459Szrj 54*a9fa9459Szrj class Output_file 55*a9fa9459Szrj { 56*a9fa9459Szrj public: 57*a9fa9459Szrj Output_file(const char* name); 58*a9fa9459Szrj 59*a9fa9459Szrj // Indicate that this is a temporary file which should not be 60*a9fa9459Szrj // output. 61*a9fa9459Szrj void set_is_temporary()62*a9fa9459Szrj set_is_temporary() 63*a9fa9459Szrj { this->is_temporary_ = true; } 64*a9fa9459Szrj 65*a9fa9459Szrj // Try to open an existing file. Returns false if the file doesn't 66*a9fa9459Szrj // exist, has a size of 0 or can't be mmaped. This method is 67*a9fa9459Szrj // thread-unsafe. If BASE_NAME is not NULL, use the contents of 68*a9fa9459Szrj // that file as the base for incremental linking. 69*a9fa9459Szrj bool 70*a9fa9459Szrj open_base_file(const char* base_name, bool writable); 71*a9fa9459Szrj 72*a9fa9459Szrj // Open the output file. FILE_SIZE is the final size of the file. 73*a9fa9459Szrj // If the file already exists, it is deleted/truncated. This method 74*a9fa9459Szrj // is thread-unsafe. 75*a9fa9459Szrj void 76*a9fa9459Szrj open(off_t file_size); 77*a9fa9459Szrj 78*a9fa9459Szrj // Resize the output file. This method is thread-unsafe. 79*a9fa9459Szrj void 80*a9fa9459Szrj resize(off_t file_size); 81*a9fa9459Szrj 82*a9fa9459Szrj // Close the output file (flushing all buffered data) and make sure 83*a9fa9459Szrj // there are no errors. This method is thread-unsafe. 84*a9fa9459Szrj void 85*a9fa9459Szrj close(); 86*a9fa9459Szrj 87*a9fa9459Szrj // Return the size of this file. 88*a9fa9459Szrj off_t filesize()89*a9fa9459Szrj filesize() 90*a9fa9459Szrj { return this->file_size_; } 91*a9fa9459Szrj 92*a9fa9459Szrj // Return the name of this file. 93*a9fa9459Szrj const char* filename()94*a9fa9459Szrj filename() 95*a9fa9459Szrj { return this->name_; } 96*a9fa9459Szrj 97*a9fa9459Szrj // We currently always use mmap which makes the view handling quite 98*a9fa9459Szrj // simple. In the future we may support other approaches. 99*a9fa9459Szrj 100*a9fa9459Szrj // Write data to the output file. 101*a9fa9459Szrj void write(off_t offset,const void * data,size_t len)102*a9fa9459Szrj write(off_t offset, const void* data, size_t len) 103*a9fa9459Szrj { memcpy(this->base_ + offset, data, len); } 104*a9fa9459Szrj 105*a9fa9459Szrj // Get a buffer to use to write to the file, given the offset into 106*a9fa9459Szrj // the file and the size. 107*a9fa9459Szrj unsigned char* get_output_view(off_t start,size_t size)108*a9fa9459Szrj get_output_view(off_t start, size_t size) 109*a9fa9459Szrj { 110*a9fa9459Szrj gold_assert(start >= 0 111*a9fa9459Szrj && start + static_cast<off_t>(size) <= this->file_size_); 112*a9fa9459Szrj return this->base_ + start; 113*a9fa9459Szrj } 114*a9fa9459Szrj 115*a9fa9459Szrj // VIEW must have been returned by get_output_view. Write the 116*a9fa9459Szrj // buffer to the file, passing in the offset and the size. 117*a9fa9459Szrj void write_output_view(off_t,size_t,unsigned char *)118*a9fa9459Szrj write_output_view(off_t, size_t, unsigned char*) 119*a9fa9459Szrj { } 120*a9fa9459Szrj 121*a9fa9459Szrj // Get a read/write buffer. This is used when we want to write part 122*a9fa9459Szrj // of the file, read it in, and write it again. 123*a9fa9459Szrj unsigned char* get_input_output_view(off_t start,size_t size)124*a9fa9459Szrj get_input_output_view(off_t start, size_t size) 125*a9fa9459Szrj { return this->get_output_view(start, size); } 126*a9fa9459Szrj 127*a9fa9459Szrj // Write a read/write buffer back to the file. 128*a9fa9459Szrj void write_input_output_view(off_t,size_t,unsigned char *)129*a9fa9459Szrj write_input_output_view(off_t, size_t, unsigned char*) 130*a9fa9459Szrj { } 131*a9fa9459Szrj 132*a9fa9459Szrj // Get a read buffer. This is used when we just want to read part 133*a9fa9459Szrj // of the file back it in. 134*a9fa9459Szrj const unsigned char* get_input_view(off_t start,size_t size)135*a9fa9459Szrj get_input_view(off_t start, size_t size) 136*a9fa9459Szrj { return this->get_output_view(start, size); } 137*a9fa9459Szrj 138*a9fa9459Szrj // Release a read bfufer. 139*a9fa9459Szrj void free_input_view(off_t,size_t,const unsigned char *)140*a9fa9459Szrj free_input_view(off_t, size_t, const unsigned char*) 141*a9fa9459Szrj { } 142*a9fa9459Szrj 143*a9fa9459Szrj private: 144*a9fa9459Szrj // Map the file into memory or, if that fails, allocate anonymous 145*a9fa9459Szrj // memory. 146*a9fa9459Szrj void 147*a9fa9459Szrj map(); 148*a9fa9459Szrj 149*a9fa9459Szrj // Allocate anonymous memory for the file. 150*a9fa9459Szrj bool 151*a9fa9459Szrj map_anonymous(); 152*a9fa9459Szrj 153*a9fa9459Szrj // Map the file into memory. 154*a9fa9459Szrj bool 155*a9fa9459Szrj map_no_anonymous(bool); 156*a9fa9459Szrj 157*a9fa9459Szrj // Unmap the file from memory (and flush to disk buffers). 158*a9fa9459Szrj void 159*a9fa9459Szrj unmap(); 160*a9fa9459Szrj 161*a9fa9459Szrj // File name. 162*a9fa9459Szrj const char* name_; 163*a9fa9459Szrj // File descriptor. 164*a9fa9459Szrj int o_; 165*a9fa9459Szrj // File size. 166*a9fa9459Szrj off_t file_size_; 167*a9fa9459Szrj // Base of file mapped into memory. 168*a9fa9459Szrj unsigned char* base_; 169*a9fa9459Szrj // True iff base_ points to a memory buffer rather than an output file. 170*a9fa9459Szrj bool map_is_anonymous_; 171*a9fa9459Szrj // True if base_ was allocated using new rather than mmap. 172*a9fa9459Szrj bool map_is_allocated_; 173*a9fa9459Szrj // True if this is a temporary file which should not be output. 174*a9fa9459Szrj bool is_temporary_; 175*a9fa9459Szrj }; 176*a9fa9459Szrj 177*a9fa9459Szrj // An abtract class for data which has to go into the output file. 178*a9fa9459Szrj 179*a9fa9459Szrj class Output_data 180*a9fa9459Szrj { 181*a9fa9459Szrj public: Output_data()182*a9fa9459Szrj explicit Output_data() 183*a9fa9459Szrj : address_(0), data_size_(0), offset_(-1), 184*a9fa9459Szrj is_address_valid_(false), is_data_size_valid_(false), 185*a9fa9459Szrj is_offset_valid_(false), is_data_size_fixed_(false), 186*a9fa9459Szrj has_dynamic_reloc_(false) 187*a9fa9459Szrj { } 188*a9fa9459Szrj 189*a9fa9459Szrj virtual 190*a9fa9459Szrj ~Output_data(); 191*a9fa9459Szrj 192*a9fa9459Szrj // Return the address. For allocated sections, this is only valid 193*a9fa9459Szrj // after Layout::finalize is finished. 194*a9fa9459Szrj uint64_t address()195*a9fa9459Szrj address() const 196*a9fa9459Szrj { 197*a9fa9459Szrj gold_assert(this->is_address_valid_); 198*a9fa9459Szrj return this->address_; 199*a9fa9459Szrj } 200*a9fa9459Szrj 201*a9fa9459Szrj // Return the size of the data. For allocated sections, this must 202*a9fa9459Szrj // be valid after Layout::finalize calls set_address, but need not 203*a9fa9459Szrj // be valid before then. 204*a9fa9459Szrj off_t data_size()205*a9fa9459Szrj data_size() const 206*a9fa9459Szrj { 207*a9fa9459Szrj gold_assert(this->is_data_size_valid_); 208*a9fa9459Szrj return this->data_size_; 209*a9fa9459Szrj } 210*a9fa9459Szrj 211*a9fa9459Szrj // Get the current data size. 212*a9fa9459Szrj off_t current_data_size()213*a9fa9459Szrj current_data_size() const 214*a9fa9459Szrj { return this->current_data_size_for_child(); } 215*a9fa9459Szrj 216*a9fa9459Szrj // Return true if data size is fixed. 217*a9fa9459Szrj bool is_data_size_fixed()218*a9fa9459Szrj is_data_size_fixed() const 219*a9fa9459Szrj { return this->is_data_size_fixed_; } 220*a9fa9459Szrj 221*a9fa9459Szrj // Return the file offset. This is only valid after 222*a9fa9459Szrj // Layout::finalize is finished. For some non-allocated sections, 223*a9fa9459Szrj // it may not be valid until near the end of the link. 224*a9fa9459Szrj off_t offset()225*a9fa9459Szrj offset() const 226*a9fa9459Szrj { 227*a9fa9459Szrj gold_assert(this->is_offset_valid_); 228*a9fa9459Szrj return this->offset_; 229*a9fa9459Szrj } 230*a9fa9459Szrj 231*a9fa9459Szrj // Reset the address, file offset and data size. This essentially 232*a9fa9459Szrj // disables the sanity testing about duplicate and unknown settings. 233*a9fa9459Szrj void reset_address_and_file_offset()234*a9fa9459Szrj reset_address_and_file_offset() 235*a9fa9459Szrj { 236*a9fa9459Szrj this->is_address_valid_ = false; 237*a9fa9459Szrj this->is_offset_valid_ = false; 238*a9fa9459Szrj if (!this->is_data_size_fixed_) 239*a9fa9459Szrj this->is_data_size_valid_ = false; 240*a9fa9459Szrj this->do_reset_address_and_file_offset(); 241*a9fa9459Szrj } 242*a9fa9459Szrj 243*a9fa9459Szrj // As above, but just for data size. 244*a9fa9459Szrj void reset_data_size()245*a9fa9459Szrj reset_data_size() 246*a9fa9459Szrj { 247*a9fa9459Szrj if (!this->is_data_size_fixed_) 248*a9fa9459Szrj this->is_data_size_valid_ = false; 249*a9fa9459Szrj } 250*a9fa9459Szrj 251*a9fa9459Szrj // Return true if address and file offset already have reset values. In 252*a9fa9459Szrj // other words, calling reset_address_and_file_offset will not change them. 253*a9fa9459Szrj bool address_and_file_offset_have_reset_values()254*a9fa9459Szrj address_and_file_offset_have_reset_values() const 255*a9fa9459Szrj { return this->do_address_and_file_offset_have_reset_values(); } 256*a9fa9459Szrj 257*a9fa9459Szrj // Return the required alignment. 258*a9fa9459Szrj uint64_t addralign()259*a9fa9459Szrj addralign() const 260*a9fa9459Szrj { return this->do_addralign(); } 261*a9fa9459Szrj 262*a9fa9459Szrj // Return whether this has a load address. 263*a9fa9459Szrj bool has_load_address()264*a9fa9459Szrj has_load_address() const 265*a9fa9459Szrj { return this->do_has_load_address(); } 266*a9fa9459Szrj 267*a9fa9459Szrj // Return the load address. 268*a9fa9459Szrj uint64_t load_address()269*a9fa9459Szrj load_address() const 270*a9fa9459Szrj { return this->do_load_address(); } 271*a9fa9459Szrj 272*a9fa9459Szrj // Return whether this is an Output_section. 273*a9fa9459Szrj bool is_section()274*a9fa9459Szrj is_section() const 275*a9fa9459Szrj { return this->do_is_section(); } 276*a9fa9459Szrj 277*a9fa9459Szrj // Return whether this is an Output_section of the specified type. 278*a9fa9459Szrj bool is_section_type(elfcpp::Elf_Word stt)279*a9fa9459Szrj is_section_type(elfcpp::Elf_Word stt) const 280*a9fa9459Szrj { return this->do_is_section_type(stt); } 281*a9fa9459Szrj 282*a9fa9459Szrj // Return whether this is an Output_section with the specified flag 283*a9fa9459Szrj // set. 284*a9fa9459Szrj bool is_section_flag_set(elfcpp::Elf_Xword shf)285*a9fa9459Szrj is_section_flag_set(elfcpp::Elf_Xword shf) const 286*a9fa9459Szrj { return this->do_is_section_flag_set(shf); } 287*a9fa9459Szrj 288*a9fa9459Szrj // Return the output section that this goes in, if there is one. 289*a9fa9459Szrj Output_section* output_section()290*a9fa9459Szrj output_section() 291*a9fa9459Szrj { return this->do_output_section(); } 292*a9fa9459Szrj 293*a9fa9459Szrj const Output_section* output_section()294*a9fa9459Szrj output_section() const 295*a9fa9459Szrj { return this->do_output_section(); } 296*a9fa9459Szrj 297*a9fa9459Szrj // Return the output section index, if there is an output section. 298*a9fa9459Szrj unsigned int out_shndx()299*a9fa9459Szrj out_shndx() const 300*a9fa9459Szrj { return this->do_out_shndx(); } 301*a9fa9459Szrj 302*a9fa9459Szrj // Set the output section index, if this is an output section. 303*a9fa9459Szrj void set_out_shndx(unsigned int shndx)304*a9fa9459Szrj set_out_shndx(unsigned int shndx) 305*a9fa9459Szrj { this->do_set_out_shndx(shndx); } 306*a9fa9459Szrj 307*a9fa9459Szrj // Set the address and file offset of this data, and finalize the 308*a9fa9459Szrj // size of the data. This is called during Layout::finalize for 309*a9fa9459Szrj // allocated sections. 310*a9fa9459Szrj void set_address_and_file_offset(uint64_t addr,off_t off)311*a9fa9459Szrj set_address_and_file_offset(uint64_t addr, off_t off) 312*a9fa9459Szrj { 313*a9fa9459Szrj this->set_address(addr); 314*a9fa9459Szrj this->set_file_offset(off); 315*a9fa9459Szrj this->finalize_data_size(); 316*a9fa9459Szrj } 317*a9fa9459Szrj 318*a9fa9459Szrj // Set the address. 319*a9fa9459Szrj void set_address(uint64_t addr)320*a9fa9459Szrj set_address(uint64_t addr) 321*a9fa9459Szrj { 322*a9fa9459Szrj gold_assert(!this->is_address_valid_); 323*a9fa9459Szrj this->address_ = addr; 324*a9fa9459Szrj this->is_address_valid_ = true; 325*a9fa9459Szrj } 326*a9fa9459Szrj 327*a9fa9459Szrj // Set the file offset. 328*a9fa9459Szrj void set_file_offset(off_t off)329*a9fa9459Szrj set_file_offset(off_t off) 330*a9fa9459Szrj { 331*a9fa9459Szrj gold_assert(!this->is_offset_valid_); 332*a9fa9459Szrj this->offset_ = off; 333*a9fa9459Szrj this->is_offset_valid_ = true; 334*a9fa9459Szrj } 335*a9fa9459Szrj 336*a9fa9459Szrj // Update the data size without finalizing it. 337*a9fa9459Szrj void pre_finalize_data_size()338*a9fa9459Szrj pre_finalize_data_size() 339*a9fa9459Szrj { 340*a9fa9459Szrj if (!this->is_data_size_valid_) 341*a9fa9459Szrj { 342*a9fa9459Szrj // Tell the child class to update the data size. 343*a9fa9459Szrj this->update_data_size(); 344*a9fa9459Szrj } 345*a9fa9459Szrj } 346*a9fa9459Szrj 347*a9fa9459Szrj // Finalize the data size. 348*a9fa9459Szrj void finalize_data_size()349*a9fa9459Szrj finalize_data_size() 350*a9fa9459Szrj { 351*a9fa9459Szrj if (!this->is_data_size_valid_) 352*a9fa9459Szrj { 353*a9fa9459Szrj // Tell the child class to set the data size. 354*a9fa9459Szrj this->set_final_data_size(); 355*a9fa9459Szrj gold_assert(this->is_data_size_valid_); 356*a9fa9459Szrj } 357*a9fa9459Szrj } 358*a9fa9459Szrj 359*a9fa9459Szrj // Set the TLS offset. Called only for SHT_TLS sections. 360*a9fa9459Szrj void set_tls_offset(uint64_t tls_base)361*a9fa9459Szrj set_tls_offset(uint64_t tls_base) 362*a9fa9459Szrj { this->do_set_tls_offset(tls_base); } 363*a9fa9459Szrj 364*a9fa9459Szrj // Return the TLS offset, relative to the base of the TLS segment. 365*a9fa9459Szrj // Valid only for SHT_TLS sections. 366*a9fa9459Szrj uint64_t tls_offset()367*a9fa9459Szrj tls_offset() const 368*a9fa9459Szrj { return this->do_tls_offset(); } 369*a9fa9459Szrj 370*a9fa9459Szrj // Write the data to the output file. This is called after 371*a9fa9459Szrj // Layout::finalize is complete. 372*a9fa9459Szrj void write(Output_file * file)373*a9fa9459Szrj write(Output_file* file) 374*a9fa9459Szrj { this->do_write(file); } 375*a9fa9459Szrj 376*a9fa9459Szrj // This is called by Layout::finalize to note that the sizes of 377*a9fa9459Szrj // allocated sections must now be fixed. 378*a9fa9459Szrj static void layout_complete()379*a9fa9459Szrj layout_complete() 380*a9fa9459Szrj { Output_data::allocated_sizes_are_fixed = true; } 381*a9fa9459Szrj 382*a9fa9459Szrj // Used to check that layout has been done. 383*a9fa9459Szrj static bool is_layout_complete()384*a9fa9459Szrj is_layout_complete() 385*a9fa9459Szrj { return Output_data::allocated_sizes_are_fixed; } 386*a9fa9459Szrj 387*a9fa9459Szrj // Note that a dynamic reloc has been applied to this data. 388*a9fa9459Szrj void add_dynamic_reloc()389*a9fa9459Szrj add_dynamic_reloc() 390*a9fa9459Szrj { this->has_dynamic_reloc_ = true; } 391*a9fa9459Szrj 392*a9fa9459Szrj // Return whether a dynamic reloc has been applied. 393*a9fa9459Szrj bool has_dynamic_reloc()394*a9fa9459Szrj has_dynamic_reloc() const 395*a9fa9459Szrj { return this->has_dynamic_reloc_; } 396*a9fa9459Szrj 397*a9fa9459Szrj // Whether the address is valid. 398*a9fa9459Szrj bool is_address_valid()399*a9fa9459Szrj is_address_valid() const 400*a9fa9459Szrj { return this->is_address_valid_; } 401*a9fa9459Szrj 402*a9fa9459Szrj // Whether the file offset is valid. 403*a9fa9459Szrj bool is_offset_valid()404*a9fa9459Szrj is_offset_valid() const 405*a9fa9459Szrj { return this->is_offset_valid_; } 406*a9fa9459Szrj 407*a9fa9459Szrj // Whether the data size is valid. 408*a9fa9459Szrj bool is_data_size_valid()409*a9fa9459Szrj is_data_size_valid() const 410*a9fa9459Szrj { return this->is_data_size_valid_; } 411*a9fa9459Szrj 412*a9fa9459Szrj // Print information to the map file. 413*a9fa9459Szrj void print_to_mapfile(Mapfile * mapfile)414*a9fa9459Szrj print_to_mapfile(Mapfile* mapfile) const 415*a9fa9459Szrj { return this->do_print_to_mapfile(mapfile); } 416*a9fa9459Szrj 417*a9fa9459Szrj protected: 418*a9fa9459Szrj // Functions that child classes may or in some cases must implement. 419*a9fa9459Szrj 420*a9fa9459Szrj // Write the data to the output file. 421*a9fa9459Szrj virtual void 422*a9fa9459Szrj do_write(Output_file*) = 0; 423*a9fa9459Szrj 424*a9fa9459Szrj // Return the required alignment. 425*a9fa9459Szrj virtual uint64_t 426*a9fa9459Szrj do_addralign() const = 0; 427*a9fa9459Szrj 428*a9fa9459Szrj // Return whether this has a load address. 429*a9fa9459Szrj virtual bool do_has_load_address()430*a9fa9459Szrj do_has_load_address() const 431*a9fa9459Szrj { return false; } 432*a9fa9459Szrj 433*a9fa9459Szrj // Return the load address. 434*a9fa9459Szrj virtual uint64_t do_load_address()435*a9fa9459Szrj do_load_address() const 436*a9fa9459Szrj { gold_unreachable(); } 437*a9fa9459Szrj 438*a9fa9459Szrj // Return whether this is an Output_section. 439*a9fa9459Szrj virtual bool do_is_section()440*a9fa9459Szrj do_is_section() const 441*a9fa9459Szrj { return false; } 442*a9fa9459Szrj 443*a9fa9459Szrj // Return whether this is an Output_section of the specified type. 444*a9fa9459Szrj // This only needs to be implement by Output_section. 445*a9fa9459Szrj virtual bool do_is_section_type(elfcpp::Elf_Word)446*a9fa9459Szrj do_is_section_type(elfcpp::Elf_Word) const 447*a9fa9459Szrj { return false; } 448*a9fa9459Szrj 449*a9fa9459Szrj // Return whether this is an Output_section with the specific flag 450*a9fa9459Szrj // set. This only needs to be implemented by Output_section. 451*a9fa9459Szrj virtual bool do_is_section_flag_set(elfcpp::Elf_Xword)452*a9fa9459Szrj do_is_section_flag_set(elfcpp::Elf_Xword) const 453*a9fa9459Szrj { return false; } 454*a9fa9459Szrj 455*a9fa9459Szrj // Return the output section, if there is one. 456*a9fa9459Szrj virtual Output_section* do_output_section()457*a9fa9459Szrj do_output_section() 458*a9fa9459Szrj { return NULL; } 459*a9fa9459Szrj 460*a9fa9459Szrj virtual const Output_section* do_output_section()461*a9fa9459Szrj do_output_section() const 462*a9fa9459Szrj { return NULL; } 463*a9fa9459Szrj 464*a9fa9459Szrj // Return the output section index, if there is an output section. 465*a9fa9459Szrj virtual unsigned int do_out_shndx()466*a9fa9459Szrj do_out_shndx() const 467*a9fa9459Szrj { gold_unreachable(); } 468*a9fa9459Szrj 469*a9fa9459Szrj // Set the output section index, if this is an output section. 470*a9fa9459Szrj virtual void do_set_out_shndx(unsigned int)471*a9fa9459Szrj do_set_out_shndx(unsigned int) 472*a9fa9459Szrj { gold_unreachable(); } 473*a9fa9459Szrj 474*a9fa9459Szrj // This is a hook for derived classes to set the preliminary data size. 475*a9fa9459Szrj // This is called by pre_finalize_data_size, normally called during 476*a9fa9459Szrj // Layout::finalize, before the section address is set, and is used 477*a9fa9459Szrj // during an incremental update, when we need to know the size of a 478*a9fa9459Szrj // section before allocating space in the output file. For classes 479*a9fa9459Szrj // where the current data size is up to date, this default version of 480*a9fa9459Szrj // the method can be inherited. 481*a9fa9459Szrj virtual void update_data_size()482*a9fa9459Szrj update_data_size() 483*a9fa9459Szrj { } 484*a9fa9459Szrj 485*a9fa9459Szrj // This is a hook for derived classes to set the data size. This is 486*a9fa9459Szrj // called by finalize_data_size, normally called during 487*a9fa9459Szrj // Layout::finalize, when the section address is set. 488*a9fa9459Szrj virtual void set_final_data_size()489*a9fa9459Szrj set_final_data_size() 490*a9fa9459Szrj { gold_unreachable(); } 491*a9fa9459Szrj 492*a9fa9459Szrj // A hook for resetting the address and file offset. 493*a9fa9459Szrj virtual void do_reset_address_and_file_offset()494*a9fa9459Szrj do_reset_address_and_file_offset() 495*a9fa9459Szrj { } 496*a9fa9459Szrj 497*a9fa9459Szrj // Return true if address and file offset already have reset values. In 498*a9fa9459Szrj // other words, calling reset_address_and_file_offset will not change them. 499*a9fa9459Szrj // A child class overriding do_reset_address_and_file_offset may need to 500*a9fa9459Szrj // also override this. 501*a9fa9459Szrj virtual bool do_address_and_file_offset_have_reset_values()502*a9fa9459Szrj do_address_and_file_offset_have_reset_values() const 503*a9fa9459Szrj { return !this->is_address_valid_ && !this->is_offset_valid_; } 504*a9fa9459Szrj 505*a9fa9459Szrj // Set the TLS offset. Called only for SHT_TLS sections. 506*a9fa9459Szrj virtual void do_set_tls_offset(uint64_t)507*a9fa9459Szrj do_set_tls_offset(uint64_t) 508*a9fa9459Szrj { gold_unreachable(); } 509*a9fa9459Szrj 510*a9fa9459Szrj // Return the TLS offset, relative to the base of the TLS segment. 511*a9fa9459Szrj // Valid only for SHT_TLS sections. 512*a9fa9459Szrj virtual uint64_t do_tls_offset()513*a9fa9459Szrj do_tls_offset() const 514*a9fa9459Szrj { gold_unreachable(); } 515*a9fa9459Szrj 516*a9fa9459Szrj // Print to the map file. This only needs to be implemented by 517*a9fa9459Szrj // classes which may appear in a PT_LOAD segment. 518*a9fa9459Szrj virtual void do_print_to_mapfile(Mapfile *)519*a9fa9459Szrj do_print_to_mapfile(Mapfile*) const 520*a9fa9459Szrj { gold_unreachable(); } 521*a9fa9459Szrj 522*a9fa9459Szrj // Functions that child classes may call. 523*a9fa9459Szrj 524*a9fa9459Szrj // Reset the address. The Output_section class needs this when an 525*a9fa9459Szrj // SHF_ALLOC input section is added to an output section which was 526*a9fa9459Szrj // formerly not SHF_ALLOC. 527*a9fa9459Szrj void mark_address_invalid()528*a9fa9459Szrj mark_address_invalid() 529*a9fa9459Szrj { this->is_address_valid_ = false; } 530*a9fa9459Szrj 531*a9fa9459Szrj // Set the size of the data. 532*a9fa9459Szrj void set_data_size(off_t data_size)533*a9fa9459Szrj set_data_size(off_t data_size) 534*a9fa9459Szrj { 535*a9fa9459Szrj gold_assert(!this->is_data_size_valid_ 536*a9fa9459Szrj && !this->is_data_size_fixed_); 537*a9fa9459Szrj this->data_size_ = data_size; 538*a9fa9459Szrj this->is_data_size_valid_ = true; 539*a9fa9459Szrj } 540*a9fa9459Szrj 541*a9fa9459Szrj // Fix the data size. Once it is fixed, it cannot be changed 542*a9fa9459Szrj // and the data size remains always valid. 543*a9fa9459Szrj void fix_data_size()544*a9fa9459Szrj fix_data_size() 545*a9fa9459Szrj { 546*a9fa9459Szrj gold_assert(this->is_data_size_valid_); 547*a9fa9459Szrj this->is_data_size_fixed_ = true; 548*a9fa9459Szrj } 549*a9fa9459Szrj 550*a9fa9459Szrj // Get the current data size--this is for the convenience of 551*a9fa9459Szrj // sections which build up their size over time. 552*a9fa9459Szrj off_t current_data_size_for_child()553*a9fa9459Szrj current_data_size_for_child() const 554*a9fa9459Szrj { return this->data_size_; } 555*a9fa9459Szrj 556*a9fa9459Szrj // Set the current data size--this is for the convenience of 557*a9fa9459Szrj // sections which build up their size over time. 558*a9fa9459Szrj void set_current_data_size_for_child(off_t data_size)559*a9fa9459Szrj set_current_data_size_for_child(off_t data_size) 560*a9fa9459Szrj { 561*a9fa9459Szrj gold_assert(!this->is_data_size_valid_); 562*a9fa9459Szrj this->data_size_ = data_size; 563*a9fa9459Szrj } 564*a9fa9459Szrj 565*a9fa9459Szrj // Return default alignment for the target size. 566*a9fa9459Szrj static uint64_t 567*a9fa9459Szrj default_alignment(); 568*a9fa9459Szrj 569*a9fa9459Szrj // Return default alignment for a specified size--32 or 64. 570*a9fa9459Szrj static uint64_t 571*a9fa9459Szrj default_alignment_for_size(int size); 572*a9fa9459Szrj 573*a9fa9459Szrj private: 574*a9fa9459Szrj Output_data(const Output_data&); 575*a9fa9459Szrj Output_data& operator=(const Output_data&); 576*a9fa9459Szrj 577*a9fa9459Szrj // This is used for verification, to make sure that we don't try to 578*a9fa9459Szrj // change any sizes of allocated sections after we set the section 579*a9fa9459Szrj // addresses. 580*a9fa9459Szrj static bool allocated_sizes_are_fixed; 581*a9fa9459Szrj 582*a9fa9459Szrj // Memory address in output file. 583*a9fa9459Szrj uint64_t address_; 584*a9fa9459Szrj // Size of data in output file. 585*a9fa9459Szrj off_t data_size_; 586*a9fa9459Szrj // File offset of contents in output file. 587*a9fa9459Szrj off_t offset_; 588*a9fa9459Szrj // Whether address_ is valid. 589*a9fa9459Szrj bool is_address_valid_ : 1; 590*a9fa9459Szrj // Whether data_size_ is valid. 591*a9fa9459Szrj bool is_data_size_valid_ : 1; 592*a9fa9459Szrj // Whether offset_ is valid. 593*a9fa9459Szrj bool is_offset_valid_ : 1; 594*a9fa9459Szrj // Whether data size is fixed. 595*a9fa9459Szrj bool is_data_size_fixed_ : 1; 596*a9fa9459Szrj // Whether any dynamic relocs have been applied to this section. 597*a9fa9459Szrj bool has_dynamic_reloc_ : 1; 598*a9fa9459Szrj }; 599*a9fa9459Szrj 600*a9fa9459Szrj // Output the section headers. 601*a9fa9459Szrj 602*a9fa9459Szrj class Output_section_headers : public Output_data 603*a9fa9459Szrj { 604*a9fa9459Szrj public: 605*a9fa9459Szrj Output_section_headers(const Layout*, 606*a9fa9459Szrj const Layout::Segment_list*, 607*a9fa9459Szrj const Layout::Section_list*, 608*a9fa9459Szrj const Layout::Section_list*, 609*a9fa9459Szrj const Stringpool*, 610*a9fa9459Szrj const Output_section*); 611*a9fa9459Szrj 612*a9fa9459Szrj protected: 613*a9fa9459Szrj // Write the data to the file. 614*a9fa9459Szrj void 615*a9fa9459Szrj do_write(Output_file*); 616*a9fa9459Szrj 617*a9fa9459Szrj // Return the required alignment. 618*a9fa9459Szrj uint64_t do_addralign()619*a9fa9459Szrj do_addralign() const 620*a9fa9459Szrj { return Output_data::default_alignment(); } 621*a9fa9459Szrj 622*a9fa9459Szrj // Write to a map file. 623*a9fa9459Szrj void do_print_to_mapfile(Mapfile * mapfile)624*a9fa9459Szrj do_print_to_mapfile(Mapfile* mapfile) const 625*a9fa9459Szrj { mapfile->print_output_data(this, _("** section headers")); } 626*a9fa9459Szrj 627*a9fa9459Szrj // Update the data size. 628*a9fa9459Szrj void update_data_size()629*a9fa9459Szrj update_data_size() 630*a9fa9459Szrj { this->set_data_size(this->do_size()); } 631*a9fa9459Szrj 632*a9fa9459Szrj // Set final data size. 633*a9fa9459Szrj void set_final_data_size()634*a9fa9459Szrj set_final_data_size() 635*a9fa9459Szrj { this->set_data_size(this->do_size()); } 636*a9fa9459Szrj 637*a9fa9459Szrj private: 638*a9fa9459Szrj // Write the data to the file with the right size and endianness. 639*a9fa9459Szrj template<int size, bool big_endian> 640*a9fa9459Szrj void 641*a9fa9459Szrj do_sized_write(Output_file*); 642*a9fa9459Szrj 643*a9fa9459Szrj // Compute data size. 644*a9fa9459Szrj off_t 645*a9fa9459Szrj do_size() const; 646*a9fa9459Szrj 647*a9fa9459Szrj const Layout* layout_; 648*a9fa9459Szrj const Layout::Segment_list* segment_list_; 649*a9fa9459Szrj const Layout::Section_list* section_list_; 650*a9fa9459Szrj const Layout::Section_list* unattached_section_list_; 651*a9fa9459Szrj const Stringpool* secnamepool_; 652*a9fa9459Szrj const Output_section* shstrtab_section_; 653*a9fa9459Szrj }; 654*a9fa9459Szrj 655*a9fa9459Szrj // Output the segment headers. 656*a9fa9459Szrj 657*a9fa9459Szrj class Output_segment_headers : public Output_data 658*a9fa9459Szrj { 659*a9fa9459Szrj public: 660*a9fa9459Szrj Output_segment_headers(const Layout::Segment_list& segment_list); 661*a9fa9459Szrj 662*a9fa9459Szrj protected: 663*a9fa9459Szrj // Write the data to the file. 664*a9fa9459Szrj void 665*a9fa9459Szrj do_write(Output_file*); 666*a9fa9459Szrj 667*a9fa9459Szrj // Return the required alignment. 668*a9fa9459Szrj uint64_t do_addralign()669*a9fa9459Szrj do_addralign() const 670*a9fa9459Szrj { return Output_data::default_alignment(); } 671*a9fa9459Szrj 672*a9fa9459Szrj // Write to a map file. 673*a9fa9459Szrj void do_print_to_mapfile(Mapfile * mapfile)674*a9fa9459Szrj do_print_to_mapfile(Mapfile* mapfile) const 675*a9fa9459Szrj { mapfile->print_output_data(this, _("** segment headers")); } 676*a9fa9459Szrj 677*a9fa9459Szrj // Set final data size. 678*a9fa9459Szrj void set_final_data_size()679*a9fa9459Szrj set_final_data_size() 680*a9fa9459Szrj { this->set_data_size(this->do_size()); } 681*a9fa9459Szrj 682*a9fa9459Szrj private: 683*a9fa9459Szrj // Write the data to the file with the right size and endianness. 684*a9fa9459Szrj template<int size, bool big_endian> 685*a9fa9459Szrj void 686*a9fa9459Szrj do_sized_write(Output_file*); 687*a9fa9459Szrj 688*a9fa9459Szrj // Compute the current size. 689*a9fa9459Szrj off_t 690*a9fa9459Szrj do_size() const; 691*a9fa9459Szrj 692*a9fa9459Szrj const Layout::Segment_list& segment_list_; 693*a9fa9459Szrj }; 694*a9fa9459Szrj 695*a9fa9459Szrj // Output the ELF file header. 696*a9fa9459Szrj 697*a9fa9459Szrj class Output_file_header : public Output_data 698*a9fa9459Szrj { 699*a9fa9459Szrj public: 700*a9fa9459Szrj Output_file_header(Target*, 701*a9fa9459Szrj const Symbol_table*, 702*a9fa9459Szrj const Output_segment_headers*); 703*a9fa9459Szrj 704*a9fa9459Szrj // Add information about the section headers. We lay out the ELF 705*a9fa9459Szrj // file header before we create the section headers. 706*a9fa9459Szrj void set_section_info(const Output_section_headers*, 707*a9fa9459Szrj const Output_section* shstrtab); 708*a9fa9459Szrj 709*a9fa9459Szrj protected: 710*a9fa9459Szrj // Write the data to the file. 711*a9fa9459Szrj void 712*a9fa9459Szrj do_write(Output_file*); 713*a9fa9459Szrj 714*a9fa9459Szrj // Return the required alignment. 715*a9fa9459Szrj uint64_t do_addralign()716*a9fa9459Szrj do_addralign() const 717*a9fa9459Szrj { return Output_data::default_alignment(); } 718*a9fa9459Szrj 719*a9fa9459Szrj // Write to a map file. 720*a9fa9459Szrj void do_print_to_mapfile(Mapfile * mapfile)721*a9fa9459Szrj do_print_to_mapfile(Mapfile* mapfile) const 722*a9fa9459Szrj { mapfile->print_output_data(this, _("** file header")); } 723*a9fa9459Szrj 724*a9fa9459Szrj // Set final data size. 725*a9fa9459Szrj void set_final_data_size(void)726*a9fa9459Szrj set_final_data_size(void) 727*a9fa9459Szrj { this->set_data_size(this->do_size()); } 728*a9fa9459Szrj 729*a9fa9459Szrj private: 730*a9fa9459Szrj // Write the data to the file with the right size and endianness. 731*a9fa9459Szrj template<int size, bool big_endian> 732*a9fa9459Szrj void 733*a9fa9459Szrj do_sized_write(Output_file*); 734*a9fa9459Szrj 735*a9fa9459Szrj // Return the value to use for the entry address. 736*a9fa9459Szrj template<int size> 737*a9fa9459Szrj typename elfcpp::Elf_types<size>::Elf_Addr 738*a9fa9459Szrj entry(); 739*a9fa9459Szrj 740*a9fa9459Szrj // Compute the current data size. 741*a9fa9459Szrj off_t 742*a9fa9459Szrj do_size() const; 743*a9fa9459Szrj 744*a9fa9459Szrj Target* target_; 745*a9fa9459Szrj const Symbol_table* symtab_; 746*a9fa9459Szrj const Output_segment_headers* segment_header_; 747*a9fa9459Szrj const Output_section_headers* section_header_; 748*a9fa9459Szrj const Output_section* shstrtab_; 749*a9fa9459Szrj }; 750*a9fa9459Szrj 751*a9fa9459Szrj // Output sections are mainly comprised of input sections. However, 752*a9fa9459Szrj // there are cases where we have data to write out which is not in an 753*a9fa9459Szrj // input section. Output_section_data is used in such cases. This is 754*a9fa9459Szrj // an abstract base class. 755*a9fa9459Szrj 756*a9fa9459Szrj class Output_section_data : public Output_data 757*a9fa9459Szrj { 758*a9fa9459Szrj public: Output_section_data(off_t data_size,uint64_t addralign,bool is_data_size_fixed)759*a9fa9459Szrj Output_section_data(off_t data_size, uint64_t addralign, 760*a9fa9459Szrj bool is_data_size_fixed) 761*a9fa9459Szrj : Output_data(), output_section_(NULL), addralign_(addralign) 762*a9fa9459Szrj { 763*a9fa9459Szrj this->set_data_size(data_size); 764*a9fa9459Szrj if (is_data_size_fixed) 765*a9fa9459Szrj this->fix_data_size(); 766*a9fa9459Szrj } 767*a9fa9459Szrj Output_section_data(uint64_t addralign)768*a9fa9459Szrj Output_section_data(uint64_t addralign) 769*a9fa9459Szrj : Output_data(), output_section_(NULL), addralign_(addralign) 770*a9fa9459Szrj { } 771*a9fa9459Szrj 772*a9fa9459Szrj // Return the output section. 773*a9fa9459Szrj Output_section* output_section()774*a9fa9459Szrj output_section() 775*a9fa9459Szrj { return this->output_section_; } 776*a9fa9459Szrj 777*a9fa9459Szrj const Output_section* output_section()778*a9fa9459Szrj output_section() const 779*a9fa9459Szrj { return this->output_section_; } 780*a9fa9459Szrj 781*a9fa9459Szrj // Record the output section. 782*a9fa9459Szrj void 783*a9fa9459Szrj set_output_section(Output_section* os); 784*a9fa9459Szrj 785*a9fa9459Szrj // Add an input section, for SHF_MERGE sections. This returns true 786*a9fa9459Szrj // if the section was handled. 787*a9fa9459Szrj bool add_input_section(Relobj * object,unsigned int shndx)788*a9fa9459Szrj add_input_section(Relobj* object, unsigned int shndx) 789*a9fa9459Szrj { return this->do_add_input_section(object, shndx); } 790*a9fa9459Szrj 791*a9fa9459Szrj // Given an input OBJECT, an input section index SHNDX within that 792*a9fa9459Szrj // object, and an OFFSET relative to the start of that input 793*a9fa9459Szrj // section, return whether or not the corresponding offset within 794*a9fa9459Szrj // the output section is known. If this function returns true, it 795*a9fa9459Szrj // sets *POUTPUT to the output offset. The value -1 indicates that 796*a9fa9459Szrj // this input offset is being discarded. 797*a9fa9459Szrj bool output_offset(const Relobj * object,unsigned int shndx,section_offset_type offset,section_offset_type * poutput)798*a9fa9459Szrj output_offset(const Relobj* object, unsigned int shndx, 799*a9fa9459Szrj section_offset_type offset, 800*a9fa9459Szrj section_offset_type* poutput) const 801*a9fa9459Szrj { return this->do_output_offset(object, shndx, offset, poutput); } 802*a9fa9459Szrj 803*a9fa9459Szrj // Write the contents to a buffer. This is used for sections which 804*a9fa9459Szrj // require postprocessing, such as compression. 805*a9fa9459Szrj void write_to_buffer(unsigned char * buffer)806*a9fa9459Szrj write_to_buffer(unsigned char* buffer) 807*a9fa9459Szrj { this->do_write_to_buffer(buffer); } 808*a9fa9459Szrj 809*a9fa9459Szrj // Print merge stats to stderr. This should only be called for 810*a9fa9459Szrj // SHF_MERGE sections. 811*a9fa9459Szrj void print_merge_stats(const char * section_name)812*a9fa9459Szrj print_merge_stats(const char* section_name) 813*a9fa9459Szrj { this->do_print_merge_stats(section_name); } 814*a9fa9459Szrj 815*a9fa9459Szrj protected: 816*a9fa9459Szrj // The child class must implement do_write. 817*a9fa9459Szrj 818*a9fa9459Szrj // The child class may implement specific adjustments to the output 819*a9fa9459Szrj // section. 820*a9fa9459Szrj virtual void do_adjust_output_section(Output_section *)821*a9fa9459Szrj do_adjust_output_section(Output_section*) 822*a9fa9459Szrj { } 823*a9fa9459Szrj 824*a9fa9459Szrj // May be implemented by child class. Return true if the section 825*a9fa9459Szrj // was handled. 826*a9fa9459Szrj virtual bool do_add_input_section(Relobj *,unsigned int)827*a9fa9459Szrj do_add_input_section(Relobj*, unsigned int) 828*a9fa9459Szrj { gold_unreachable(); } 829*a9fa9459Szrj 830*a9fa9459Szrj // The child class may implement output_offset. 831*a9fa9459Szrj virtual bool do_output_offset(const Relobj *,unsigned int,section_offset_type,section_offset_type *)832*a9fa9459Szrj do_output_offset(const Relobj*, unsigned int, section_offset_type, 833*a9fa9459Szrj section_offset_type*) const 834*a9fa9459Szrj { return false; } 835*a9fa9459Szrj 836*a9fa9459Szrj // The child class may implement write_to_buffer. Most child 837*a9fa9459Szrj // classes can not appear in a compressed section, and they do not 838*a9fa9459Szrj // implement this. 839*a9fa9459Szrj virtual void do_write_to_buffer(unsigned char *)840*a9fa9459Szrj do_write_to_buffer(unsigned char*) 841*a9fa9459Szrj { gold_unreachable(); } 842*a9fa9459Szrj 843*a9fa9459Szrj // Print merge statistics. 844*a9fa9459Szrj virtual void do_print_merge_stats(const char *)845*a9fa9459Szrj do_print_merge_stats(const char*) 846*a9fa9459Szrj { gold_unreachable(); } 847*a9fa9459Szrj 848*a9fa9459Szrj // Return the required alignment. 849*a9fa9459Szrj uint64_t do_addralign()850*a9fa9459Szrj do_addralign() const 851*a9fa9459Szrj { return this->addralign_; } 852*a9fa9459Szrj 853*a9fa9459Szrj // Return the output section. 854*a9fa9459Szrj Output_section* do_output_section()855*a9fa9459Szrj do_output_section() 856*a9fa9459Szrj { return this->output_section_; } 857*a9fa9459Szrj 858*a9fa9459Szrj const Output_section* do_output_section()859*a9fa9459Szrj do_output_section() const 860*a9fa9459Szrj { return this->output_section_; } 861*a9fa9459Szrj 862*a9fa9459Szrj // Return the section index of the output section. 863*a9fa9459Szrj unsigned int 864*a9fa9459Szrj do_out_shndx() const; 865*a9fa9459Szrj 866*a9fa9459Szrj // Set the alignment. 867*a9fa9459Szrj void 868*a9fa9459Szrj set_addralign(uint64_t addralign); 869*a9fa9459Szrj 870*a9fa9459Szrj private: 871*a9fa9459Szrj // The output section for this section. 872*a9fa9459Szrj Output_section* output_section_; 873*a9fa9459Szrj // The required alignment. 874*a9fa9459Szrj uint64_t addralign_; 875*a9fa9459Szrj }; 876*a9fa9459Szrj 877*a9fa9459Szrj // Some Output_section_data classes build up their data step by step, 878*a9fa9459Szrj // rather than all at once. This class provides an interface for 879*a9fa9459Szrj // them. 880*a9fa9459Szrj 881*a9fa9459Szrj class Output_section_data_build : public Output_section_data 882*a9fa9459Szrj { 883*a9fa9459Szrj public: Output_section_data_build(uint64_t addralign)884*a9fa9459Szrj Output_section_data_build(uint64_t addralign) 885*a9fa9459Szrj : Output_section_data(addralign) 886*a9fa9459Szrj { } 887*a9fa9459Szrj Output_section_data_build(off_t data_size,uint64_t addralign)888*a9fa9459Szrj Output_section_data_build(off_t data_size, uint64_t addralign) 889*a9fa9459Szrj : Output_section_data(data_size, addralign, false) 890*a9fa9459Szrj { } 891*a9fa9459Szrj 892*a9fa9459Szrj // Set the current data size. 893*a9fa9459Szrj void set_current_data_size(off_t data_size)894*a9fa9459Szrj set_current_data_size(off_t data_size) 895*a9fa9459Szrj { this->set_current_data_size_for_child(data_size); } 896*a9fa9459Szrj 897*a9fa9459Szrj protected: 898*a9fa9459Szrj // Set the final data size. 899*a9fa9459Szrj virtual void set_final_data_size()900*a9fa9459Szrj set_final_data_size() 901*a9fa9459Szrj { this->set_data_size(this->current_data_size_for_child()); } 902*a9fa9459Szrj }; 903*a9fa9459Szrj 904*a9fa9459Szrj // A simple case of Output_data in which we have constant data to 905*a9fa9459Szrj // output. 906*a9fa9459Szrj 907*a9fa9459Szrj class Output_data_const : public Output_section_data 908*a9fa9459Szrj { 909*a9fa9459Szrj public: Output_data_const(const std::string & data,uint64_t addralign)910*a9fa9459Szrj Output_data_const(const std::string& data, uint64_t addralign) 911*a9fa9459Szrj : Output_section_data(data.size(), addralign, true), data_(data) 912*a9fa9459Szrj { } 913*a9fa9459Szrj Output_data_const(const char * p,off_t len,uint64_t addralign)914*a9fa9459Szrj Output_data_const(const char* p, off_t len, uint64_t addralign) 915*a9fa9459Szrj : Output_section_data(len, addralign, true), data_(p, len) 916*a9fa9459Szrj { } 917*a9fa9459Szrj Output_data_const(const unsigned char * p,off_t len,uint64_t addralign)918*a9fa9459Szrj Output_data_const(const unsigned char* p, off_t len, uint64_t addralign) 919*a9fa9459Szrj : Output_section_data(len, addralign, true), 920*a9fa9459Szrj data_(reinterpret_cast<const char*>(p), len) 921*a9fa9459Szrj { } 922*a9fa9459Szrj 923*a9fa9459Szrj protected: 924*a9fa9459Szrj // Write the data to the output file. 925*a9fa9459Szrj void 926*a9fa9459Szrj do_write(Output_file*); 927*a9fa9459Szrj 928*a9fa9459Szrj // Write the data to a buffer. 929*a9fa9459Szrj void do_write_to_buffer(unsigned char * buffer)930*a9fa9459Szrj do_write_to_buffer(unsigned char* buffer) 931*a9fa9459Szrj { memcpy(buffer, this->data_.data(), this->data_.size()); } 932*a9fa9459Szrj 933*a9fa9459Szrj // Write to a map file. 934*a9fa9459Szrj void do_print_to_mapfile(Mapfile * mapfile)935*a9fa9459Szrj do_print_to_mapfile(Mapfile* mapfile) const 936*a9fa9459Szrj { mapfile->print_output_data(this, _("** fill")); } 937*a9fa9459Szrj 938*a9fa9459Szrj private: 939*a9fa9459Szrj std::string data_; 940*a9fa9459Szrj }; 941*a9fa9459Szrj 942*a9fa9459Szrj // Another version of Output_data with constant data, in which the 943*a9fa9459Szrj // buffer is allocated by the caller. 944*a9fa9459Szrj 945*a9fa9459Szrj class Output_data_const_buffer : public Output_section_data 946*a9fa9459Szrj { 947*a9fa9459Szrj public: Output_data_const_buffer(const unsigned char * p,off_t len,uint64_t addralign,const char * map_name)948*a9fa9459Szrj Output_data_const_buffer(const unsigned char* p, off_t len, 949*a9fa9459Szrj uint64_t addralign, const char* map_name) 950*a9fa9459Szrj : Output_section_data(len, addralign, true), 951*a9fa9459Szrj p_(p), map_name_(map_name) 952*a9fa9459Szrj { } 953*a9fa9459Szrj 954*a9fa9459Szrj protected: 955*a9fa9459Szrj // Write the data the output file. 956*a9fa9459Szrj void 957*a9fa9459Szrj do_write(Output_file*); 958*a9fa9459Szrj 959*a9fa9459Szrj // Write the data to a buffer. 960*a9fa9459Szrj void do_write_to_buffer(unsigned char * buffer)961*a9fa9459Szrj do_write_to_buffer(unsigned char* buffer) 962*a9fa9459Szrj { memcpy(buffer, this->p_, this->data_size()); } 963*a9fa9459Szrj 964*a9fa9459Szrj // Write to a map file. 965*a9fa9459Szrj void do_print_to_mapfile(Mapfile * mapfile)966*a9fa9459Szrj do_print_to_mapfile(Mapfile* mapfile) const 967*a9fa9459Szrj { mapfile->print_output_data(this, _(this->map_name_)); } 968*a9fa9459Szrj 969*a9fa9459Szrj private: 970*a9fa9459Szrj // The data to output. 971*a9fa9459Szrj const unsigned char* p_; 972*a9fa9459Szrj // Name to use in a map file. Maps are a rarely used feature, but 973*a9fa9459Szrj // the space usage is minor as aren't very many of these objects. 974*a9fa9459Szrj const char* map_name_; 975*a9fa9459Szrj }; 976*a9fa9459Szrj 977*a9fa9459Szrj // A place holder for a fixed amount of data written out via some 978*a9fa9459Szrj // other mechanism. 979*a9fa9459Szrj 980*a9fa9459Szrj class Output_data_fixed_space : public Output_section_data 981*a9fa9459Szrj { 982*a9fa9459Szrj public: Output_data_fixed_space(off_t data_size,uint64_t addralign,const char * map_name)983*a9fa9459Szrj Output_data_fixed_space(off_t data_size, uint64_t addralign, 984*a9fa9459Szrj const char* map_name) 985*a9fa9459Szrj : Output_section_data(data_size, addralign, true), 986*a9fa9459Szrj map_name_(map_name) 987*a9fa9459Szrj { } 988*a9fa9459Szrj 989*a9fa9459Szrj protected: 990*a9fa9459Szrj // Write out the data--the actual data must be written out 991*a9fa9459Szrj // elsewhere. 992*a9fa9459Szrj void do_write(Output_file *)993*a9fa9459Szrj do_write(Output_file*) 994*a9fa9459Szrj { } 995*a9fa9459Szrj 996*a9fa9459Szrj // Write to a map file. 997*a9fa9459Szrj void do_print_to_mapfile(Mapfile * mapfile)998*a9fa9459Szrj do_print_to_mapfile(Mapfile* mapfile) const 999*a9fa9459Szrj { mapfile->print_output_data(this, _(this->map_name_)); } 1000*a9fa9459Szrj 1001*a9fa9459Szrj private: 1002*a9fa9459Szrj // Name to use in a map file. Maps are a rarely used feature, but 1003*a9fa9459Szrj // the space usage is minor as aren't very many of these objects. 1004*a9fa9459Szrj const char* map_name_; 1005*a9fa9459Szrj }; 1006*a9fa9459Szrj 1007*a9fa9459Szrj // A place holder for variable sized data written out via some other 1008*a9fa9459Szrj // mechanism. 1009*a9fa9459Szrj 1010*a9fa9459Szrj class Output_data_space : public Output_section_data_build 1011*a9fa9459Szrj { 1012*a9fa9459Szrj public: Output_data_space(uint64_t addralign,const char * map_name)1013*a9fa9459Szrj explicit Output_data_space(uint64_t addralign, const char* map_name) 1014*a9fa9459Szrj : Output_section_data_build(addralign), 1015*a9fa9459Szrj map_name_(map_name) 1016*a9fa9459Szrj { } 1017*a9fa9459Szrj Output_data_space(off_t data_size,uint64_t addralign,const char * map_name)1018*a9fa9459Szrj explicit Output_data_space(off_t data_size, uint64_t addralign, 1019*a9fa9459Szrj const char* map_name) 1020*a9fa9459Szrj : Output_section_data_build(data_size, addralign), 1021*a9fa9459Szrj map_name_(map_name) 1022*a9fa9459Szrj { } 1023*a9fa9459Szrj 1024*a9fa9459Szrj // Set the alignment. 1025*a9fa9459Szrj void set_space_alignment(uint64_t align)1026*a9fa9459Szrj set_space_alignment(uint64_t align) 1027*a9fa9459Szrj { this->set_addralign(align); } 1028*a9fa9459Szrj 1029*a9fa9459Szrj protected: 1030*a9fa9459Szrj // Write out the data--the actual data must be written out 1031*a9fa9459Szrj // elsewhere. 1032*a9fa9459Szrj void do_write(Output_file *)1033*a9fa9459Szrj do_write(Output_file*) 1034*a9fa9459Szrj { } 1035*a9fa9459Szrj 1036*a9fa9459Szrj // Write to a map file. 1037*a9fa9459Szrj void do_print_to_mapfile(Mapfile * mapfile)1038*a9fa9459Szrj do_print_to_mapfile(Mapfile* mapfile) const 1039*a9fa9459Szrj { mapfile->print_output_data(this, _(this->map_name_)); } 1040*a9fa9459Szrj 1041*a9fa9459Szrj private: 1042*a9fa9459Szrj // Name to use in a map file. Maps are a rarely used feature, but 1043*a9fa9459Szrj // the space usage is minor as aren't very many of these objects. 1044*a9fa9459Szrj const char* map_name_; 1045*a9fa9459Szrj }; 1046*a9fa9459Szrj 1047*a9fa9459Szrj // Fill fixed space with zeroes. This is just like 1048*a9fa9459Szrj // Output_data_fixed_space, except that the map name is known. 1049*a9fa9459Szrj 1050*a9fa9459Szrj class Output_data_zero_fill : public Output_section_data 1051*a9fa9459Szrj { 1052*a9fa9459Szrj public: Output_data_zero_fill(off_t data_size,uint64_t addralign)1053*a9fa9459Szrj Output_data_zero_fill(off_t data_size, uint64_t addralign) 1054*a9fa9459Szrj : Output_section_data(data_size, addralign, true) 1055*a9fa9459Szrj { } 1056*a9fa9459Szrj 1057*a9fa9459Szrj protected: 1058*a9fa9459Szrj // There is no data to write out. 1059*a9fa9459Szrj void do_write(Output_file *)1060*a9fa9459Szrj do_write(Output_file*) 1061*a9fa9459Szrj { } 1062*a9fa9459Szrj 1063*a9fa9459Szrj // Write to a map file. 1064*a9fa9459Szrj void do_print_to_mapfile(Mapfile * mapfile)1065*a9fa9459Szrj do_print_to_mapfile(Mapfile* mapfile) const 1066*a9fa9459Szrj { mapfile->print_output_data(this, "** zero fill"); } 1067*a9fa9459Szrj }; 1068*a9fa9459Szrj 1069*a9fa9459Szrj // A string table which goes into an output section. 1070*a9fa9459Szrj 1071*a9fa9459Szrj class Output_data_strtab : public Output_section_data 1072*a9fa9459Szrj { 1073*a9fa9459Szrj public: Output_data_strtab(Stringpool * strtab)1074*a9fa9459Szrj Output_data_strtab(Stringpool* strtab) 1075*a9fa9459Szrj : Output_section_data(1), strtab_(strtab) 1076*a9fa9459Szrj { } 1077*a9fa9459Szrj 1078*a9fa9459Szrj protected: 1079*a9fa9459Szrj // This is called to update the section size prior to assigning 1080*a9fa9459Szrj // the address and file offset. 1081*a9fa9459Szrj void update_data_size()1082*a9fa9459Szrj update_data_size() 1083*a9fa9459Szrj { this->set_final_data_size(); } 1084*a9fa9459Szrj 1085*a9fa9459Szrj // This is called to set the address and file offset. Here we make 1086*a9fa9459Szrj // sure that the Stringpool is finalized. 1087*a9fa9459Szrj void 1088*a9fa9459Szrj set_final_data_size(); 1089*a9fa9459Szrj 1090*a9fa9459Szrj // Write out the data. 1091*a9fa9459Szrj void 1092*a9fa9459Szrj do_write(Output_file*); 1093*a9fa9459Szrj 1094*a9fa9459Szrj // Write the data to a buffer. 1095*a9fa9459Szrj void do_write_to_buffer(unsigned char * buffer)1096*a9fa9459Szrj do_write_to_buffer(unsigned char* buffer) 1097*a9fa9459Szrj { this->strtab_->write_to_buffer(buffer, this->data_size()); } 1098*a9fa9459Szrj 1099*a9fa9459Szrj // Write to a map file. 1100*a9fa9459Szrj void do_print_to_mapfile(Mapfile * mapfile)1101*a9fa9459Szrj do_print_to_mapfile(Mapfile* mapfile) const 1102*a9fa9459Szrj { mapfile->print_output_data(this, _("** string table")); } 1103*a9fa9459Szrj 1104*a9fa9459Szrj private: 1105*a9fa9459Szrj Stringpool* strtab_; 1106*a9fa9459Szrj }; 1107*a9fa9459Szrj 1108*a9fa9459Szrj // This POD class is used to represent a single reloc in the output 1109*a9fa9459Szrj // file. This could be a private class within Output_data_reloc, but 1110*a9fa9459Szrj // the templatization is complex enough that I broke it out into a 1111*a9fa9459Szrj // separate class. The class is templatized on either elfcpp::SHT_REL 1112*a9fa9459Szrj // or elfcpp::SHT_RELA, and also on whether this is a dynamic 1113*a9fa9459Szrj // relocation or an ordinary relocation. 1114*a9fa9459Szrj 1115*a9fa9459Szrj // A relocation can be against a global symbol, a local symbol, a 1116*a9fa9459Szrj // local section symbol, an output section, or the undefined symbol at 1117*a9fa9459Szrj // index 0. We represent the latter by using a NULL global symbol. 1118*a9fa9459Szrj 1119*a9fa9459Szrj template<int sh_type, bool dynamic, int size, bool big_endian> 1120*a9fa9459Szrj class Output_reloc; 1121*a9fa9459Szrj 1122*a9fa9459Szrj template<bool dynamic, int size, bool big_endian> 1123*a9fa9459Szrj class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> 1124*a9fa9459Szrj { 1125*a9fa9459Szrj public: 1126*a9fa9459Szrj typedef typename elfcpp::Elf_types<size>::Elf_Addr Address; 1127*a9fa9459Szrj typedef typename elfcpp::Elf_types<size>::Elf_Addr Addend; 1128*a9fa9459Szrj 1129*a9fa9459Szrj static const Address invalid_address = static_cast<Address>(0) - 1; 1130*a9fa9459Szrj 1131*a9fa9459Szrj // An uninitialized entry. We need this because we want to put 1132*a9fa9459Szrj // instances of this class into an STL container. Output_reloc()1133*a9fa9459Szrj Output_reloc() 1134*a9fa9459Szrj : local_sym_index_(INVALID_CODE) 1135*a9fa9459Szrj { } 1136*a9fa9459Szrj 1137*a9fa9459Szrj // We have a bunch of different constructors. They come in pairs 1138*a9fa9459Szrj // depending on how the address of the relocation is specified. It 1139*a9fa9459Szrj // can either be an offset in an Output_data or an offset in an 1140*a9fa9459Szrj // input section. 1141*a9fa9459Szrj 1142*a9fa9459Szrj // A reloc against a global symbol. 1143*a9fa9459Szrj 1144*a9fa9459Szrj Output_reloc(Symbol* gsym, unsigned int type, Output_data* od, 1145*a9fa9459Szrj Address address, bool is_relative, bool is_symbolless, 1146*a9fa9459Szrj bool use_plt_offset); 1147*a9fa9459Szrj 1148*a9fa9459Szrj Output_reloc(Symbol* gsym, unsigned int type, 1149*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 1150*a9fa9459Szrj unsigned int shndx, Address address, bool is_relative, 1151*a9fa9459Szrj bool is_symbolless, bool use_plt_offset); 1152*a9fa9459Szrj 1153*a9fa9459Szrj // A reloc against a local symbol or local section symbol. 1154*a9fa9459Szrj 1155*a9fa9459Szrj Output_reloc(Sized_relobj<size, big_endian>* relobj, 1156*a9fa9459Szrj unsigned int local_sym_index, unsigned int type, 1157*a9fa9459Szrj Output_data* od, Address address, bool is_relative, 1158*a9fa9459Szrj bool is_symbolless, bool is_section_symbol, 1159*a9fa9459Szrj bool use_plt_offset); 1160*a9fa9459Szrj 1161*a9fa9459Szrj Output_reloc(Sized_relobj<size, big_endian>* relobj, 1162*a9fa9459Szrj unsigned int local_sym_index, unsigned int type, 1163*a9fa9459Szrj unsigned int shndx, Address address, bool is_relative, 1164*a9fa9459Szrj bool is_symbolless, bool is_section_symbol, 1165*a9fa9459Szrj bool use_plt_offset); 1166*a9fa9459Szrj 1167*a9fa9459Szrj // A reloc against the STT_SECTION symbol of an output section. 1168*a9fa9459Szrj 1169*a9fa9459Szrj Output_reloc(Output_section* os, unsigned int type, Output_data* od, 1170*a9fa9459Szrj Address address, bool is_relative); 1171*a9fa9459Szrj 1172*a9fa9459Szrj Output_reloc(Output_section* os, unsigned int type, 1173*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, unsigned int shndx, 1174*a9fa9459Szrj Address address, bool is_relative); 1175*a9fa9459Szrj 1176*a9fa9459Szrj // An absolute or relative relocation with no symbol. 1177*a9fa9459Szrj 1178*a9fa9459Szrj Output_reloc(unsigned int type, Output_data* od, Address address, 1179*a9fa9459Szrj bool is_relative); 1180*a9fa9459Szrj 1181*a9fa9459Szrj Output_reloc(unsigned int type, Sized_relobj<size, big_endian>* relobj, 1182*a9fa9459Szrj unsigned int shndx, Address address, bool is_relative); 1183*a9fa9459Szrj 1184*a9fa9459Szrj // A target specific relocation. The target will be called to get 1185*a9fa9459Szrj // the symbol index, passing ARG. The type and offset will be set 1186*a9fa9459Szrj // as for other relocation types. 1187*a9fa9459Szrj 1188*a9fa9459Szrj Output_reloc(unsigned int type, void* arg, Output_data* od, 1189*a9fa9459Szrj Address address); 1190*a9fa9459Szrj 1191*a9fa9459Szrj Output_reloc(unsigned int type, void* arg, 1192*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 1193*a9fa9459Szrj unsigned int shndx, Address address); 1194*a9fa9459Szrj 1195*a9fa9459Szrj // Return the reloc type. 1196*a9fa9459Szrj unsigned int type()1197*a9fa9459Szrj type() const 1198*a9fa9459Szrj { return this->type_; } 1199*a9fa9459Szrj 1200*a9fa9459Szrj // Return whether this is a RELATIVE relocation. 1201*a9fa9459Szrj bool is_relative()1202*a9fa9459Szrj is_relative() const 1203*a9fa9459Szrj { return this->is_relative_; } 1204*a9fa9459Szrj 1205*a9fa9459Szrj // Return whether this is a relocation which should not use 1206*a9fa9459Szrj // a symbol, but which obtains its addend from a symbol. 1207*a9fa9459Szrj bool is_symbolless()1208*a9fa9459Szrj is_symbolless() const 1209*a9fa9459Szrj { return this->is_symbolless_; } 1210*a9fa9459Szrj 1211*a9fa9459Szrj // Return whether this is against a local section symbol. 1212*a9fa9459Szrj bool is_local_section_symbol()1213*a9fa9459Szrj is_local_section_symbol() const 1214*a9fa9459Szrj { 1215*a9fa9459Szrj return (this->local_sym_index_ != GSYM_CODE 1216*a9fa9459Szrj && this->local_sym_index_ != SECTION_CODE 1217*a9fa9459Szrj && this->local_sym_index_ != INVALID_CODE 1218*a9fa9459Szrj && this->local_sym_index_ != TARGET_CODE 1219*a9fa9459Szrj && this->is_section_symbol_); 1220*a9fa9459Szrj } 1221*a9fa9459Szrj 1222*a9fa9459Szrj // Return whether this is a target specific relocation. 1223*a9fa9459Szrj bool is_target_specific()1224*a9fa9459Szrj is_target_specific() const 1225*a9fa9459Szrj { return this->local_sym_index_ == TARGET_CODE; } 1226*a9fa9459Szrj 1227*a9fa9459Szrj // Return the argument to pass to the target for a target specific 1228*a9fa9459Szrj // relocation. 1229*a9fa9459Szrj void* target_arg()1230*a9fa9459Szrj target_arg() const 1231*a9fa9459Szrj { 1232*a9fa9459Szrj gold_assert(this->local_sym_index_ == TARGET_CODE); 1233*a9fa9459Szrj return this->u1_.arg; 1234*a9fa9459Szrj } 1235*a9fa9459Szrj 1236*a9fa9459Szrj // For a local section symbol, return the offset of the input 1237*a9fa9459Szrj // section within the output section. ADDEND is the addend being 1238*a9fa9459Szrj // applied to the input section. 1239*a9fa9459Szrj Address 1240*a9fa9459Szrj local_section_offset(Addend addend) const; 1241*a9fa9459Szrj 1242*a9fa9459Szrj // Get the value of the symbol referred to by a Rel relocation when 1243*a9fa9459Szrj // we are adding the given ADDEND. 1244*a9fa9459Szrj Address 1245*a9fa9459Szrj symbol_value(Addend addend) const; 1246*a9fa9459Szrj 1247*a9fa9459Szrj // If this relocation is against an input section, return the 1248*a9fa9459Szrj // relocatable object containing the input section. 1249*a9fa9459Szrj Sized_relobj<size, big_endian>* get_relobj()1250*a9fa9459Szrj get_relobj() const 1251*a9fa9459Szrj { 1252*a9fa9459Szrj if (this->shndx_ == INVALID_CODE) 1253*a9fa9459Szrj return NULL; 1254*a9fa9459Szrj return this->u2_.relobj; 1255*a9fa9459Szrj } 1256*a9fa9459Szrj 1257*a9fa9459Szrj // Write the reloc entry to an output view. 1258*a9fa9459Szrj void 1259*a9fa9459Szrj write(unsigned char* pov) const; 1260*a9fa9459Szrj 1261*a9fa9459Szrj // Write the offset and info fields to Write_rel. 1262*a9fa9459Szrj template<typename Write_rel> 1263*a9fa9459Szrj void write_rel(Write_rel*) const; 1264*a9fa9459Szrj 1265*a9fa9459Szrj // This is used when sorting dynamic relocs. Return -1 to sort this 1266*a9fa9459Szrj // reloc before R2, 0 to sort the same as R2, 1 to sort after R2. 1267*a9fa9459Szrj int 1268*a9fa9459Szrj compare(const Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>& r2) 1269*a9fa9459Szrj const; 1270*a9fa9459Szrj 1271*a9fa9459Szrj // Return whether this reloc should be sorted before the argument 1272*a9fa9459Szrj // when sorting dynamic relocs. 1273*a9fa9459Szrj bool sort_before(const Output_reloc<elfcpp::SHT_REL,dynamic,size,big_endian> & r2)1274*a9fa9459Szrj sort_before(const Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>& 1275*a9fa9459Szrj r2) const 1276*a9fa9459Szrj { return this->compare(r2) < 0; } 1277*a9fa9459Szrj 1278*a9fa9459Szrj // Return the symbol index. 1279*a9fa9459Szrj unsigned int 1280*a9fa9459Szrj get_symbol_index() const; 1281*a9fa9459Szrj 1282*a9fa9459Szrj // Return the output address. 1283*a9fa9459Szrj Address 1284*a9fa9459Szrj get_address() const; 1285*a9fa9459Szrj 1286*a9fa9459Szrj private: 1287*a9fa9459Szrj // Record that we need a dynamic symbol index. 1288*a9fa9459Szrj void 1289*a9fa9459Szrj set_needs_dynsym_index(); 1290*a9fa9459Szrj 1291*a9fa9459Szrj // Codes for local_sym_index_. 1292*a9fa9459Szrj enum 1293*a9fa9459Szrj { 1294*a9fa9459Szrj // Global symbol. 1295*a9fa9459Szrj GSYM_CODE = -1U, 1296*a9fa9459Szrj // Output section. 1297*a9fa9459Szrj SECTION_CODE = -2U, 1298*a9fa9459Szrj // Target specific. 1299*a9fa9459Szrj TARGET_CODE = -3U, 1300*a9fa9459Szrj // Invalid uninitialized entry. 1301*a9fa9459Szrj INVALID_CODE = -4U 1302*a9fa9459Szrj }; 1303*a9fa9459Szrj 1304*a9fa9459Szrj union 1305*a9fa9459Szrj { 1306*a9fa9459Szrj // For a local symbol or local section symbol 1307*a9fa9459Szrj // (this->local_sym_index_ >= 0), the object. We will never 1308*a9fa9459Szrj // generate a relocation against a local symbol in a dynamic 1309*a9fa9459Szrj // object; that doesn't make sense. And our callers will always 1310*a9fa9459Szrj // be templatized, so we use Sized_relobj here. 1311*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj; 1312*a9fa9459Szrj // For a global symbol (this->local_sym_index_ == GSYM_CODE, the 1313*a9fa9459Szrj // symbol. If this is NULL, it indicates a relocation against the 1314*a9fa9459Szrj // undefined 0 symbol. 1315*a9fa9459Szrj Symbol* gsym; 1316*a9fa9459Szrj // For a relocation against an output section 1317*a9fa9459Szrj // (this->local_sym_index_ == SECTION_CODE), the output section. 1318*a9fa9459Szrj Output_section* os; 1319*a9fa9459Szrj // For a target specific relocation, an argument to pass to the 1320*a9fa9459Szrj // target. 1321*a9fa9459Szrj void* arg; 1322*a9fa9459Szrj } u1_; 1323*a9fa9459Szrj union 1324*a9fa9459Szrj { 1325*a9fa9459Szrj // If this->shndx_ is not INVALID CODE, the object which holds the 1326*a9fa9459Szrj // input section being used to specify the reloc address. 1327*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj; 1328*a9fa9459Szrj // If this->shndx_ is INVALID_CODE, the output data being used to 1329*a9fa9459Szrj // specify the reloc address. This may be NULL if the reloc 1330*a9fa9459Szrj // address is absolute. 1331*a9fa9459Szrj Output_data* od; 1332*a9fa9459Szrj } u2_; 1333*a9fa9459Szrj // The address offset within the input section or the Output_data. 1334*a9fa9459Szrj Address address_; 1335*a9fa9459Szrj // This is GSYM_CODE for a global symbol, or SECTION_CODE for a 1336*a9fa9459Szrj // relocation against an output section, or TARGET_CODE for a target 1337*a9fa9459Szrj // specific relocation, or INVALID_CODE for an uninitialized value. 1338*a9fa9459Szrj // Otherwise, for a local symbol (this->is_section_symbol_ is 1339*a9fa9459Szrj // false), the local symbol index. For a local section symbol 1340*a9fa9459Szrj // (this->is_section_symbol_ is true), the section index in the 1341*a9fa9459Szrj // input file. 1342*a9fa9459Szrj unsigned int local_sym_index_; 1343*a9fa9459Szrj // The reloc type--a processor specific code. 1344*a9fa9459Szrj unsigned int type_ : 28; 1345*a9fa9459Szrj // True if the relocation is a RELATIVE relocation. 1346*a9fa9459Szrj bool is_relative_ : 1; 1347*a9fa9459Szrj // True if the relocation is one which should not use 1348*a9fa9459Szrj // a symbol, but which obtains its addend from a symbol. 1349*a9fa9459Szrj bool is_symbolless_ : 1; 1350*a9fa9459Szrj // True if the relocation is against a section symbol. 1351*a9fa9459Szrj bool is_section_symbol_ : 1; 1352*a9fa9459Szrj // True if the addend should be the PLT offset. 1353*a9fa9459Szrj // (Used only for RELA, but stored here for space.) 1354*a9fa9459Szrj bool use_plt_offset_ : 1; 1355*a9fa9459Szrj // If the reloc address is an input section in an object, the 1356*a9fa9459Szrj // section index. This is INVALID_CODE if the reloc address is 1357*a9fa9459Szrj // specified in some other way. 1358*a9fa9459Szrj unsigned int shndx_; 1359*a9fa9459Szrj }; 1360*a9fa9459Szrj 1361*a9fa9459Szrj // The SHT_RELA version of Output_reloc<>. This is just derived from 1362*a9fa9459Szrj // the SHT_REL version of Output_reloc, but it adds an addend. 1363*a9fa9459Szrj 1364*a9fa9459Szrj template<bool dynamic, int size, bool big_endian> 1365*a9fa9459Szrj class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> 1366*a9fa9459Szrj { 1367*a9fa9459Szrj public: 1368*a9fa9459Szrj typedef typename elfcpp::Elf_types<size>::Elf_Addr Address; 1369*a9fa9459Szrj typedef typename elfcpp::Elf_types<size>::Elf_Addr Addend; 1370*a9fa9459Szrj 1371*a9fa9459Szrj // An uninitialized entry. Output_reloc()1372*a9fa9459Szrj Output_reloc() 1373*a9fa9459Szrj : rel_() 1374*a9fa9459Szrj { } 1375*a9fa9459Szrj 1376*a9fa9459Szrj // A reloc against a global symbol. 1377*a9fa9459Szrj Output_reloc(Symbol * gsym,unsigned int type,Output_data * od,Address address,Addend addend,bool is_relative,bool is_symbolless,bool use_plt_offset)1378*a9fa9459Szrj Output_reloc(Symbol* gsym, unsigned int type, Output_data* od, 1379*a9fa9459Szrj Address address, Addend addend, bool is_relative, 1380*a9fa9459Szrj bool is_symbolless, bool use_plt_offset) 1381*a9fa9459Szrj : rel_(gsym, type, od, address, is_relative, is_symbolless, 1382*a9fa9459Szrj use_plt_offset), 1383*a9fa9459Szrj addend_(addend) 1384*a9fa9459Szrj { } 1385*a9fa9459Szrj Output_reloc(Symbol * gsym,unsigned int type,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address,Addend addend,bool is_relative,bool is_symbolless,bool use_plt_offset)1386*a9fa9459Szrj Output_reloc(Symbol* gsym, unsigned int type, 1387*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 1388*a9fa9459Szrj unsigned int shndx, Address address, Addend addend, 1389*a9fa9459Szrj bool is_relative, bool is_symbolless, bool use_plt_offset) 1390*a9fa9459Szrj : rel_(gsym, type, relobj, shndx, address, is_relative, 1391*a9fa9459Szrj is_symbolless, use_plt_offset), addend_(addend) 1392*a9fa9459Szrj { } 1393*a9fa9459Szrj 1394*a9fa9459Szrj // A reloc against a local symbol. 1395*a9fa9459Szrj Output_reloc(Sized_relobj<size,big_endian> * relobj,unsigned int local_sym_index,unsigned int type,Output_data * od,Address address,Addend addend,bool is_relative,bool is_symbolless,bool is_section_symbol,bool use_plt_offset)1396*a9fa9459Szrj Output_reloc(Sized_relobj<size, big_endian>* relobj, 1397*a9fa9459Szrj unsigned int local_sym_index, unsigned int type, 1398*a9fa9459Szrj Output_data* od, Address address, 1399*a9fa9459Szrj Addend addend, bool is_relative, 1400*a9fa9459Szrj bool is_symbolless, bool is_section_symbol, 1401*a9fa9459Szrj bool use_plt_offset) 1402*a9fa9459Szrj : rel_(relobj, local_sym_index, type, od, address, is_relative, 1403*a9fa9459Szrj is_symbolless, is_section_symbol, use_plt_offset), 1404*a9fa9459Szrj addend_(addend) 1405*a9fa9459Szrj { } 1406*a9fa9459Szrj Output_reloc(Sized_relobj<size,big_endian> * relobj,unsigned int local_sym_index,unsigned int type,unsigned int shndx,Address address,Addend addend,bool is_relative,bool is_symbolless,bool is_section_symbol,bool use_plt_offset)1407*a9fa9459Szrj Output_reloc(Sized_relobj<size, big_endian>* relobj, 1408*a9fa9459Szrj unsigned int local_sym_index, unsigned int type, 1409*a9fa9459Szrj unsigned int shndx, Address address, 1410*a9fa9459Szrj Addend addend, bool is_relative, 1411*a9fa9459Szrj bool is_symbolless, bool is_section_symbol, 1412*a9fa9459Szrj bool use_plt_offset) 1413*a9fa9459Szrj : rel_(relobj, local_sym_index, type, shndx, address, is_relative, 1414*a9fa9459Szrj is_symbolless, is_section_symbol, use_plt_offset), 1415*a9fa9459Szrj addend_(addend) 1416*a9fa9459Szrj { } 1417*a9fa9459Szrj 1418*a9fa9459Szrj // A reloc against the STT_SECTION symbol of an output section. 1419*a9fa9459Szrj Output_reloc(Output_section * os,unsigned int type,Output_data * od,Address address,Addend addend,bool is_relative)1420*a9fa9459Szrj Output_reloc(Output_section* os, unsigned int type, Output_data* od, 1421*a9fa9459Szrj Address address, Addend addend, bool is_relative) 1422*a9fa9459Szrj : rel_(os, type, od, address, is_relative), addend_(addend) 1423*a9fa9459Szrj { } 1424*a9fa9459Szrj Output_reloc(Output_section * os,unsigned int type,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address,Addend addend,bool is_relative)1425*a9fa9459Szrj Output_reloc(Output_section* os, unsigned int type, 1426*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 1427*a9fa9459Szrj unsigned int shndx, Address address, Addend addend, 1428*a9fa9459Szrj bool is_relative) 1429*a9fa9459Szrj : rel_(os, type, relobj, shndx, address, is_relative), addend_(addend) 1430*a9fa9459Szrj { } 1431*a9fa9459Szrj 1432*a9fa9459Szrj // An absolute or relative relocation with no symbol. 1433*a9fa9459Szrj Output_reloc(unsigned int type,Output_data * od,Address address,Addend addend,bool is_relative)1434*a9fa9459Szrj Output_reloc(unsigned int type, Output_data* od, Address address, 1435*a9fa9459Szrj Addend addend, bool is_relative) 1436*a9fa9459Szrj : rel_(type, od, address, is_relative), addend_(addend) 1437*a9fa9459Szrj { } 1438*a9fa9459Szrj Output_reloc(unsigned int type,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address,Addend addend,bool is_relative)1439*a9fa9459Szrj Output_reloc(unsigned int type, Sized_relobj<size, big_endian>* relobj, 1440*a9fa9459Szrj unsigned int shndx, Address address, Addend addend, 1441*a9fa9459Szrj bool is_relative) 1442*a9fa9459Szrj : rel_(type, relobj, shndx, address, is_relative), addend_(addend) 1443*a9fa9459Szrj { } 1444*a9fa9459Szrj 1445*a9fa9459Szrj // A target specific relocation. The target will be called to get 1446*a9fa9459Szrj // the symbol index and the addend, passing ARG. The type and 1447*a9fa9459Szrj // offset will be set as for other relocation types. 1448*a9fa9459Szrj Output_reloc(unsigned int type,void * arg,Output_data * od,Address address,Addend addend)1449*a9fa9459Szrj Output_reloc(unsigned int type, void* arg, Output_data* od, 1450*a9fa9459Szrj Address address, Addend addend) 1451*a9fa9459Szrj : rel_(type, arg, od, address), addend_(addend) 1452*a9fa9459Szrj { } 1453*a9fa9459Szrj Output_reloc(unsigned int type,void * arg,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address,Addend addend)1454*a9fa9459Szrj Output_reloc(unsigned int type, void* arg, 1455*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 1456*a9fa9459Szrj unsigned int shndx, Address address, Addend addend) 1457*a9fa9459Szrj : rel_(type, arg, relobj, shndx, address), addend_(addend) 1458*a9fa9459Szrj { } 1459*a9fa9459Szrj 1460*a9fa9459Szrj // Return whether this is a RELATIVE relocation. 1461*a9fa9459Szrj bool is_relative()1462*a9fa9459Szrj is_relative() const 1463*a9fa9459Szrj { return this->rel_.is_relative(); } 1464*a9fa9459Szrj 1465*a9fa9459Szrj // Return whether this is a relocation which should not use 1466*a9fa9459Szrj // a symbol, but which obtains its addend from a symbol. 1467*a9fa9459Szrj bool is_symbolless()1468*a9fa9459Szrj is_symbolless() const 1469*a9fa9459Szrj { return this->rel_.is_symbolless(); } 1470*a9fa9459Szrj 1471*a9fa9459Szrj // If this relocation is against an input section, return the 1472*a9fa9459Szrj // relocatable object containing the input section. 1473*a9fa9459Szrj Sized_relobj<size, big_endian>* get_relobj()1474*a9fa9459Szrj get_relobj() const 1475*a9fa9459Szrj { return this->rel_.get_relobj(); } 1476*a9fa9459Szrj 1477*a9fa9459Szrj // Write the reloc entry to an output view. 1478*a9fa9459Szrj void 1479*a9fa9459Szrj write(unsigned char* pov) const; 1480*a9fa9459Szrj 1481*a9fa9459Szrj // Return whether this reloc should be sorted before the argument 1482*a9fa9459Szrj // when sorting dynamic relocs. 1483*a9fa9459Szrj bool sort_before(const Output_reloc<elfcpp::SHT_RELA,dynamic,size,big_endian> & r2)1484*a9fa9459Szrj sort_before(const Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>& 1485*a9fa9459Szrj r2) const 1486*a9fa9459Szrj { 1487*a9fa9459Szrj int i = this->rel_.compare(r2.rel_); 1488*a9fa9459Szrj if (i < 0) 1489*a9fa9459Szrj return true; 1490*a9fa9459Szrj else if (i > 0) 1491*a9fa9459Szrj return false; 1492*a9fa9459Szrj else 1493*a9fa9459Szrj return this->addend_ < r2.addend_; 1494*a9fa9459Szrj } 1495*a9fa9459Szrj 1496*a9fa9459Szrj private: 1497*a9fa9459Szrj // The basic reloc. 1498*a9fa9459Szrj Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> rel_; 1499*a9fa9459Szrj // The addend. 1500*a9fa9459Szrj Addend addend_; 1501*a9fa9459Szrj }; 1502*a9fa9459Szrj 1503*a9fa9459Szrj // Output_data_reloc_generic is a non-template base class for 1504*a9fa9459Szrj // Output_data_reloc_base. This gives the generic code a way to hold 1505*a9fa9459Szrj // a pointer to a reloc section. 1506*a9fa9459Szrj 1507*a9fa9459Szrj class Output_data_reloc_generic : public Output_section_data_build 1508*a9fa9459Szrj { 1509*a9fa9459Szrj public: Output_data_reloc_generic(int size,bool sort_relocs)1510*a9fa9459Szrj Output_data_reloc_generic(int size, bool sort_relocs) 1511*a9fa9459Szrj : Output_section_data_build(Output_data::default_alignment_for_size(size)), 1512*a9fa9459Szrj relative_reloc_count_(0), sort_relocs_(sort_relocs) 1513*a9fa9459Szrj { } 1514*a9fa9459Szrj 1515*a9fa9459Szrj // Return the number of relative relocs in this section. 1516*a9fa9459Szrj size_t relative_reloc_count()1517*a9fa9459Szrj relative_reloc_count() const 1518*a9fa9459Szrj { return this->relative_reloc_count_; } 1519*a9fa9459Szrj 1520*a9fa9459Szrj // Whether we should sort the relocs. 1521*a9fa9459Szrj bool sort_relocs()1522*a9fa9459Szrj sort_relocs() const 1523*a9fa9459Szrj { return this->sort_relocs_; } 1524*a9fa9459Szrj 1525*a9fa9459Szrj // Add a reloc of type TYPE against the global symbol GSYM. The 1526*a9fa9459Szrj // relocation applies to the data at offset ADDRESS within OD. 1527*a9fa9459Szrj virtual void 1528*a9fa9459Szrj add_global_generic(Symbol* gsym, unsigned int type, Output_data* od, 1529*a9fa9459Szrj uint64_t address, uint64_t addend) = 0; 1530*a9fa9459Szrj 1531*a9fa9459Szrj // Add a reloc of type TYPE against the global symbol GSYM. The 1532*a9fa9459Szrj // relocation applies to data at offset ADDRESS within section SHNDX 1533*a9fa9459Szrj // of object file RELOBJ. OD is the associated output section. 1534*a9fa9459Szrj virtual void 1535*a9fa9459Szrj add_global_generic(Symbol* gsym, unsigned int type, Output_data* od, 1536*a9fa9459Szrj Relobj* relobj, unsigned int shndx, uint64_t address, 1537*a9fa9459Szrj uint64_t addend) = 0; 1538*a9fa9459Szrj 1539*a9fa9459Szrj // Add a reloc of type TYPE against the local symbol LOCAL_SYM_INDEX 1540*a9fa9459Szrj // in RELOBJ. The relocation applies to the data at offset ADDRESS 1541*a9fa9459Szrj // within OD. 1542*a9fa9459Szrj virtual void 1543*a9fa9459Szrj add_local_generic(Relobj* relobj, unsigned int local_sym_index, 1544*a9fa9459Szrj unsigned int type, Output_data* od, uint64_t address, 1545*a9fa9459Szrj uint64_t addend) = 0; 1546*a9fa9459Szrj 1547*a9fa9459Szrj // Add a reloc of type TYPE against the local symbol LOCAL_SYM_INDEX 1548*a9fa9459Szrj // in RELOBJ. The relocation applies to the data at offset ADDRESS 1549*a9fa9459Szrj // within section SHNDX of RELOBJ. OD is the associated output 1550*a9fa9459Szrj // section. 1551*a9fa9459Szrj virtual void 1552*a9fa9459Szrj add_local_generic(Relobj* relobj, unsigned int local_sym_index, 1553*a9fa9459Szrj unsigned int type, Output_data* od, unsigned int shndx, 1554*a9fa9459Szrj uint64_t address, uint64_t addend) = 0; 1555*a9fa9459Szrj 1556*a9fa9459Szrj // Add a reloc of type TYPE against the STT_SECTION symbol of the 1557*a9fa9459Szrj // output section OS. The relocation applies to the data at offset 1558*a9fa9459Szrj // ADDRESS within OD. 1559*a9fa9459Szrj virtual void 1560*a9fa9459Szrj add_output_section_generic(Output_section *os, unsigned int type, 1561*a9fa9459Szrj Output_data* od, uint64_t address, 1562*a9fa9459Szrj uint64_t addend) = 0; 1563*a9fa9459Szrj 1564*a9fa9459Szrj // Add a reloc of type TYPE against the STT_SECTION symbol of the 1565*a9fa9459Szrj // output section OS. The relocation applies to the data at offset 1566*a9fa9459Szrj // ADDRESS within section SHNDX of RELOBJ. OD is the associated 1567*a9fa9459Szrj // output section. 1568*a9fa9459Szrj virtual void 1569*a9fa9459Szrj add_output_section_generic(Output_section* os, unsigned int type, 1570*a9fa9459Szrj Output_data* od, Relobj* relobj, 1571*a9fa9459Szrj unsigned int shndx, uint64_t address, 1572*a9fa9459Szrj uint64_t addend) = 0; 1573*a9fa9459Szrj 1574*a9fa9459Szrj protected: 1575*a9fa9459Szrj // Note that we've added another relative reloc. 1576*a9fa9459Szrj void bump_relative_reloc_count()1577*a9fa9459Szrj bump_relative_reloc_count() 1578*a9fa9459Szrj { ++this->relative_reloc_count_; } 1579*a9fa9459Szrj 1580*a9fa9459Szrj private: 1581*a9fa9459Szrj // The number of relative relocs added to this section. This is to 1582*a9fa9459Szrj // support DT_RELCOUNT. 1583*a9fa9459Szrj size_t relative_reloc_count_; 1584*a9fa9459Szrj // Whether to sort the relocations when writing them out, to make 1585*a9fa9459Szrj // the dynamic linker more efficient. 1586*a9fa9459Szrj bool sort_relocs_; 1587*a9fa9459Szrj }; 1588*a9fa9459Szrj 1589*a9fa9459Szrj // Output_data_reloc is used to manage a section containing relocs. 1590*a9fa9459Szrj // SH_TYPE is either elfcpp::SHT_REL or elfcpp::SHT_RELA. DYNAMIC 1591*a9fa9459Szrj // indicates whether this is a dynamic relocation or a normal 1592*a9fa9459Szrj // relocation. Output_data_reloc_base is a base class. 1593*a9fa9459Szrj // Output_data_reloc is the real class, which we specialize based on 1594*a9fa9459Szrj // the reloc type. 1595*a9fa9459Szrj 1596*a9fa9459Szrj template<int sh_type, bool dynamic, int size, bool big_endian> 1597*a9fa9459Szrj class Output_data_reloc_base : public Output_data_reloc_generic 1598*a9fa9459Szrj { 1599*a9fa9459Szrj public: 1600*a9fa9459Szrj typedef Output_reloc<sh_type, dynamic, size, big_endian> Output_reloc_type; 1601*a9fa9459Szrj typedef typename Output_reloc_type::Address Address; 1602*a9fa9459Szrj static const int reloc_size = 1603*a9fa9459Szrj Reloc_types<sh_type, size, big_endian>::reloc_size; 1604*a9fa9459Szrj 1605*a9fa9459Szrj // Construct the section. Output_data_reloc_base(bool sort_relocs)1606*a9fa9459Szrj Output_data_reloc_base(bool sort_relocs) 1607*a9fa9459Szrj : Output_data_reloc_generic(size, sort_relocs) 1608*a9fa9459Szrj { } 1609*a9fa9459Szrj 1610*a9fa9459Szrj protected: 1611*a9fa9459Szrj // Write out the data. 1612*a9fa9459Szrj void 1613*a9fa9459Szrj do_write(Output_file*); 1614*a9fa9459Szrj 1615*a9fa9459Szrj // Generic implementation of do_write, allowing a customized 1616*a9fa9459Szrj // class for writing the output relocation (e.g., for MIPS-64). 1617*a9fa9459Szrj template<class Output_reloc_writer> 1618*a9fa9459Szrj void do_write_generic(Output_file * of)1619*a9fa9459Szrj do_write_generic(Output_file* of) 1620*a9fa9459Szrj { 1621*a9fa9459Szrj const off_t off = this->offset(); 1622*a9fa9459Szrj const off_t oview_size = this->data_size(); 1623*a9fa9459Szrj unsigned char* const oview = of->get_output_view(off, oview_size); 1624*a9fa9459Szrj 1625*a9fa9459Szrj if (this->sort_relocs()) 1626*a9fa9459Szrj { 1627*a9fa9459Szrj gold_assert(dynamic); 1628*a9fa9459Szrj std::sort(this->relocs_.begin(), this->relocs_.end(), 1629*a9fa9459Szrj Sort_relocs_comparison()); 1630*a9fa9459Szrj } 1631*a9fa9459Szrj 1632*a9fa9459Szrj unsigned char* pov = oview; 1633*a9fa9459Szrj for (typename Relocs::const_iterator p = this->relocs_.begin(); 1634*a9fa9459Szrj p != this->relocs_.end(); 1635*a9fa9459Szrj ++p) 1636*a9fa9459Szrj { 1637*a9fa9459Szrj Output_reloc_writer::write(p, pov); 1638*a9fa9459Szrj pov += reloc_size; 1639*a9fa9459Szrj } 1640*a9fa9459Szrj 1641*a9fa9459Szrj gold_assert(pov - oview == oview_size); 1642*a9fa9459Szrj 1643*a9fa9459Szrj of->write_output_view(off, oview_size, oview); 1644*a9fa9459Szrj 1645*a9fa9459Szrj // We no longer need the relocation entries. 1646*a9fa9459Szrj this->relocs_.clear(); 1647*a9fa9459Szrj } 1648*a9fa9459Szrj 1649*a9fa9459Szrj // Set the entry size and the link. 1650*a9fa9459Szrj void 1651*a9fa9459Szrj do_adjust_output_section(Output_section* os); 1652*a9fa9459Szrj 1653*a9fa9459Szrj // Write to a map file. 1654*a9fa9459Szrj void do_print_to_mapfile(Mapfile * mapfile)1655*a9fa9459Szrj do_print_to_mapfile(Mapfile* mapfile) const 1656*a9fa9459Szrj { 1657*a9fa9459Szrj mapfile->print_output_data(this, 1658*a9fa9459Szrj (dynamic 1659*a9fa9459Szrj ? _("** dynamic relocs") 1660*a9fa9459Szrj : _("** relocs"))); 1661*a9fa9459Szrj } 1662*a9fa9459Szrj 1663*a9fa9459Szrj // Add a relocation entry. 1664*a9fa9459Szrj void add(Output_data * od,const Output_reloc_type & reloc)1665*a9fa9459Szrj add(Output_data* od, const Output_reloc_type& reloc) 1666*a9fa9459Szrj { 1667*a9fa9459Szrj this->relocs_.push_back(reloc); 1668*a9fa9459Szrj this->set_current_data_size(this->relocs_.size() * reloc_size); 1669*a9fa9459Szrj if (dynamic) 1670*a9fa9459Szrj od->add_dynamic_reloc(); 1671*a9fa9459Szrj if (reloc.is_relative()) 1672*a9fa9459Szrj this->bump_relative_reloc_count(); 1673*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj = reloc.get_relobj(); 1674*a9fa9459Szrj if (relobj != NULL) 1675*a9fa9459Szrj relobj->add_dyn_reloc(this->relocs_.size() - 1); 1676*a9fa9459Szrj } 1677*a9fa9459Szrj 1678*a9fa9459Szrj private: 1679*a9fa9459Szrj typedef std::vector<Output_reloc_type> Relocs; 1680*a9fa9459Szrj 1681*a9fa9459Szrj // The class used to sort the relocations. 1682*a9fa9459Szrj struct Sort_relocs_comparison 1683*a9fa9459Szrj { 1684*a9fa9459Szrj bool operatorSort_relocs_comparison1685*a9fa9459Szrj operator()(const Output_reloc_type& r1, const Output_reloc_type& r2) const 1686*a9fa9459Szrj { return r1.sort_before(r2); } 1687*a9fa9459Szrj }; 1688*a9fa9459Szrj 1689*a9fa9459Szrj // The relocations in this section. 1690*a9fa9459Szrj Relocs relocs_; 1691*a9fa9459Szrj }; 1692*a9fa9459Szrj 1693*a9fa9459Szrj // The class which callers actually create. 1694*a9fa9459Szrj 1695*a9fa9459Szrj template<int sh_type, bool dynamic, int size, bool big_endian> 1696*a9fa9459Szrj class Output_data_reloc; 1697*a9fa9459Szrj 1698*a9fa9459Szrj // The SHT_REL version of Output_data_reloc. 1699*a9fa9459Szrj 1700*a9fa9459Szrj template<bool dynamic, int size, bool big_endian> 1701*a9fa9459Szrj class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> 1702*a9fa9459Szrj : public Output_data_reloc_base<elfcpp::SHT_REL, dynamic, size, big_endian> 1703*a9fa9459Szrj { 1704*a9fa9459Szrj private: 1705*a9fa9459Szrj typedef Output_data_reloc_base<elfcpp::SHT_REL, dynamic, size, 1706*a9fa9459Szrj big_endian> Base; 1707*a9fa9459Szrj 1708*a9fa9459Szrj public: 1709*a9fa9459Szrj typedef typename Base::Output_reloc_type Output_reloc_type; 1710*a9fa9459Szrj typedef typename Output_reloc_type::Address Address; 1711*a9fa9459Szrj Output_data_reloc(bool sr)1712*a9fa9459Szrj Output_data_reloc(bool sr) 1713*a9fa9459Szrj : Output_data_reloc_base<elfcpp::SHT_REL, dynamic, size, big_endian>(sr) 1714*a9fa9459Szrj { } 1715*a9fa9459Szrj 1716*a9fa9459Szrj // Add a reloc against a global symbol. 1717*a9fa9459Szrj 1718*a9fa9459Szrj void add_global(Symbol * gsym,unsigned int type,Output_data * od,Address address)1719*a9fa9459Szrj add_global(Symbol* gsym, unsigned int type, Output_data* od, Address address) 1720*a9fa9459Szrj { 1721*a9fa9459Szrj this->add(od, Output_reloc_type(gsym, type, od, address, 1722*a9fa9459Szrj false, false, false)); 1723*a9fa9459Szrj } 1724*a9fa9459Szrj 1725*a9fa9459Szrj void add_global(Symbol * gsym,unsigned int type,Output_data * od,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address)1726*a9fa9459Szrj add_global(Symbol* gsym, unsigned int type, Output_data* od, 1727*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 1728*a9fa9459Szrj unsigned int shndx, Address address) 1729*a9fa9459Szrj { 1730*a9fa9459Szrj this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address, 1731*a9fa9459Szrj false, false, false)); 1732*a9fa9459Szrj } 1733*a9fa9459Szrj 1734*a9fa9459Szrj void add_global_generic(Symbol * gsym,unsigned int type,Output_data * od,uint64_t address,uint64_t addend)1735*a9fa9459Szrj add_global_generic(Symbol* gsym, unsigned int type, Output_data* od, 1736*a9fa9459Szrj uint64_t address, uint64_t addend) 1737*a9fa9459Szrj { 1738*a9fa9459Szrj gold_assert(addend == 0); 1739*a9fa9459Szrj this->add(od, Output_reloc_type(gsym, type, od, 1740*a9fa9459Szrj convert_types<Address, uint64_t>(address), 1741*a9fa9459Szrj false, false, false)); 1742*a9fa9459Szrj } 1743*a9fa9459Szrj 1744*a9fa9459Szrj void add_global_generic(Symbol * gsym,unsigned int type,Output_data * od,Relobj * relobj,unsigned int shndx,uint64_t address,uint64_t addend)1745*a9fa9459Szrj add_global_generic(Symbol* gsym, unsigned int type, Output_data* od, 1746*a9fa9459Szrj Relobj* relobj, unsigned int shndx, uint64_t address, 1747*a9fa9459Szrj uint64_t addend) 1748*a9fa9459Szrj { 1749*a9fa9459Szrj gold_assert(addend == 0); 1750*a9fa9459Szrj Sized_relobj<size, big_endian>* sized_relobj = 1751*a9fa9459Szrj static_cast<Sized_relobj<size, big_endian>*>(relobj); 1752*a9fa9459Szrj this->add(od, Output_reloc_type(gsym, type, sized_relobj, shndx, 1753*a9fa9459Szrj convert_types<Address, uint64_t>(address), 1754*a9fa9459Szrj false, false, false)); 1755*a9fa9459Szrj } 1756*a9fa9459Szrj 1757*a9fa9459Szrj // Add a RELATIVE reloc against a global symbol. The final relocation 1758*a9fa9459Szrj // will not reference the symbol. 1759*a9fa9459Szrj 1760*a9fa9459Szrj void add_global_relative(Symbol * gsym,unsigned int type,Output_data * od,Address address)1761*a9fa9459Szrj add_global_relative(Symbol* gsym, unsigned int type, Output_data* od, 1762*a9fa9459Szrj Address address) 1763*a9fa9459Szrj { 1764*a9fa9459Szrj this->add(od, Output_reloc_type(gsym, type, od, address, true, true, 1765*a9fa9459Szrj false)); 1766*a9fa9459Szrj } 1767*a9fa9459Szrj 1768*a9fa9459Szrj void add_global_relative(Symbol * gsym,unsigned int type,Output_data * od,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address)1769*a9fa9459Szrj add_global_relative(Symbol* gsym, unsigned int type, Output_data* od, 1770*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 1771*a9fa9459Szrj unsigned int shndx, Address address) 1772*a9fa9459Szrj { 1773*a9fa9459Szrj this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address, 1774*a9fa9459Szrj true, true, false)); 1775*a9fa9459Szrj } 1776*a9fa9459Szrj 1777*a9fa9459Szrj // Add a global relocation which does not use a symbol for the relocation, 1778*a9fa9459Szrj // but which gets its addend from a symbol. 1779*a9fa9459Szrj 1780*a9fa9459Szrj void add_symbolless_global_addend(Symbol * gsym,unsigned int type,Output_data * od,Address address)1781*a9fa9459Szrj add_symbolless_global_addend(Symbol* gsym, unsigned int type, 1782*a9fa9459Szrj Output_data* od, Address address) 1783*a9fa9459Szrj { 1784*a9fa9459Szrj this->add(od, Output_reloc_type(gsym, type, od, address, false, true, 1785*a9fa9459Szrj false)); 1786*a9fa9459Szrj } 1787*a9fa9459Szrj 1788*a9fa9459Szrj void add_symbolless_global_addend(Symbol * gsym,unsigned int type,Output_data * od,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address)1789*a9fa9459Szrj add_symbolless_global_addend(Symbol* gsym, unsigned int type, 1790*a9fa9459Szrj Output_data* od, 1791*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 1792*a9fa9459Szrj unsigned int shndx, Address address) 1793*a9fa9459Szrj { 1794*a9fa9459Szrj this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address, 1795*a9fa9459Szrj false, true, false)); 1796*a9fa9459Szrj } 1797*a9fa9459Szrj 1798*a9fa9459Szrj // Add a reloc against a local symbol. 1799*a9fa9459Szrj 1800*a9fa9459Szrj void add_local(Sized_relobj<size,big_endian> * relobj,unsigned int local_sym_index,unsigned int type,Output_data * od,Address address)1801*a9fa9459Szrj add_local(Sized_relobj<size, big_endian>* relobj, 1802*a9fa9459Szrj unsigned int local_sym_index, unsigned int type, 1803*a9fa9459Szrj Output_data* od, Address address) 1804*a9fa9459Szrj { 1805*a9fa9459Szrj this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, 1806*a9fa9459Szrj address, false, false, false, false)); 1807*a9fa9459Szrj } 1808*a9fa9459Szrj 1809*a9fa9459Szrj void add_local(Sized_relobj<size,big_endian> * relobj,unsigned int local_sym_index,unsigned int type,Output_data * od,unsigned int shndx,Address address)1810*a9fa9459Szrj add_local(Sized_relobj<size, big_endian>* relobj, 1811*a9fa9459Szrj unsigned int local_sym_index, unsigned int type, 1812*a9fa9459Szrj Output_data* od, unsigned int shndx, Address address) 1813*a9fa9459Szrj { 1814*a9fa9459Szrj this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, 1815*a9fa9459Szrj address, false, false, false, false)); 1816*a9fa9459Szrj } 1817*a9fa9459Szrj 1818*a9fa9459Szrj void add_local_generic(Relobj * relobj,unsigned int local_sym_index,unsigned int type,Output_data * od,uint64_t address,uint64_t addend)1819*a9fa9459Szrj add_local_generic(Relobj* relobj, unsigned int local_sym_index, 1820*a9fa9459Szrj unsigned int type, Output_data* od, uint64_t address, 1821*a9fa9459Szrj uint64_t addend) 1822*a9fa9459Szrj { 1823*a9fa9459Szrj gold_assert(addend == 0); 1824*a9fa9459Szrj Sized_relobj<size, big_endian>* sized_relobj = 1825*a9fa9459Szrj static_cast<Sized_relobj<size, big_endian> *>(relobj); 1826*a9fa9459Szrj this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, od, 1827*a9fa9459Szrj convert_types<Address, uint64_t>(address), 1828*a9fa9459Szrj false, false, false, false)); 1829*a9fa9459Szrj } 1830*a9fa9459Szrj 1831*a9fa9459Szrj void add_local_generic(Relobj * relobj,unsigned int local_sym_index,unsigned int type,Output_data * od,unsigned int shndx,uint64_t address,uint64_t addend)1832*a9fa9459Szrj add_local_generic(Relobj* relobj, unsigned int local_sym_index, 1833*a9fa9459Szrj unsigned int type, Output_data* od, unsigned int shndx, 1834*a9fa9459Szrj uint64_t address, uint64_t addend) 1835*a9fa9459Szrj { 1836*a9fa9459Szrj gold_assert(addend == 0); 1837*a9fa9459Szrj Sized_relobj<size, big_endian>* sized_relobj = 1838*a9fa9459Szrj static_cast<Sized_relobj<size, big_endian>*>(relobj); 1839*a9fa9459Szrj this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, shndx, 1840*a9fa9459Szrj convert_types<Address, uint64_t>(address), 1841*a9fa9459Szrj false, false, false, false)); 1842*a9fa9459Szrj } 1843*a9fa9459Szrj 1844*a9fa9459Szrj // Add a RELATIVE reloc against a local symbol. 1845*a9fa9459Szrj 1846*a9fa9459Szrj void add_local_relative(Sized_relobj<size,big_endian> * relobj,unsigned int local_sym_index,unsigned int type,Output_data * od,Address address)1847*a9fa9459Szrj add_local_relative(Sized_relobj<size, big_endian>* relobj, 1848*a9fa9459Szrj unsigned int local_sym_index, unsigned int type, 1849*a9fa9459Szrj Output_data* od, Address address) 1850*a9fa9459Szrj { 1851*a9fa9459Szrj this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, 1852*a9fa9459Szrj address, true, true, false, false)); 1853*a9fa9459Szrj } 1854*a9fa9459Szrj 1855*a9fa9459Szrj void add_local_relative(Sized_relobj<size,big_endian> * relobj,unsigned int local_sym_index,unsigned int type,Output_data * od,unsigned int shndx,Address address)1856*a9fa9459Szrj add_local_relative(Sized_relobj<size, big_endian>* relobj, 1857*a9fa9459Szrj unsigned int local_sym_index, unsigned int type, 1858*a9fa9459Szrj Output_data* od, unsigned int shndx, Address address) 1859*a9fa9459Szrj { 1860*a9fa9459Szrj this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, 1861*a9fa9459Szrj address, true, true, false, false)); 1862*a9fa9459Szrj } 1863*a9fa9459Szrj 1864*a9fa9459Szrj void add_local_relative(Sized_relobj<size,big_endian> * relobj,unsigned int local_sym_index,unsigned int type,Output_data * od,unsigned int shndx,Address address,bool use_plt_offset)1865*a9fa9459Szrj add_local_relative(Sized_relobj<size, big_endian>* relobj, 1866*a9fa9459Szrj unsigned int local_sym_index, unsigned int type, 1867*a9fa9459Szrj Output_data* od, unsigned int shndx, Address address, 1868*a9fa9459Szrj bool use_plt_offset) 1869*a9fa9459Szrj { 1870*a9fa9459Szrj this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, 1871*a9fa9459Szrj address, true, true, false, 1872*a9fa9459Szrj use_plt_offset)); 1873*a9fa9459Szrj } 1874*a9fa9459Szrj 1875*a9fa9459Szrj // Add a local relocation which does not use a symbol for the relocation, 1876*a9fa9459Szrj // but which gets its addend from a symbol. 1877*a9fa9459Szrj 1878*a9fa9459Szrj void add_symbolless_local_addend(Sized_relobj<size,big_endian> * relobj,unsigned int local_sym_index,unsigned int type,Output_data * od,Address address)1879*a9fa9459Szrj add_symbolless_local_addend(Sized_relobj<size, big_endian>* relobj, 1880*a9fa9459Szrj unsigned int local_sym_index, unsigned int type, 1881*a9fa9459Szrj Output_data* od, Address address) 1882*a9fa9459Szrj { 1883*a9fa9459Szrj this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, 1884*a9fa9459Szrj address, false, true, false, false)); 1885*a9fa9459Szrj } 1886*a9fa9459Szrj 1887*a9fa9459Szrj void add_symbolless_local_addend(Sized_relobj<size,big_endian> * relobj,unsigned int local_sym_index,unsigned int type,Output_data * od,unsigned int shndx,Address address)1888*a9fa9459Szrj add_symbolless_local_addend(Sized_relobj<size, big_endian>* relobj, 1889*a9fa9459Szrj unsigned int local_sym_index, unsigned int type, 1890*a9fa9459Szrj Output_data* od, unsigned int shndx, 1891*a9fa9459Szrj Address address) 1892*a9fa9459Szrj { 1893*a9fa9459Szrj this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, 1894*a9fa9459Szrj address, false, true, false, false)); 1895*a9fa9459Szrj } 1896*a9fa9459Szrj 1897*a9fa9459Szrj // Add a reloc against a local section symbol. This will be 1898*a9fa9459Szrj // converted into a reloc against the STT_SECTION symbol of the 1899*a9fa9459Szrj // output section. 1900*a9fa9459Szrj 1901*a9fa9459Szrj void add_local_section(Sized_relobj<size,big_endian> * relobj,unsigned int input_shndx,unsigned int type,Output_data * od,Address address)1902*a9fa9459Szrj add_local_section(Sized_relobj<size, big_endian>* relobj, 1903*a9fa9459Szrj unsigned int input_shndx, unsigned int type, 1904*a9fa9459Szrj Output_data* od, Address address) 1905*a9fa9459Szrj { 1906*a9fa9459Szrj this->add(od, Output_reloc_type(relobj, input_shndx, type, od, 1907*a9fa9459Szrj address, false, false, true, false)); 1908*a9fa9459Szrj } 1909*a9fa9459Szrj 1910*a9fa9459Szrj void add_local_section(Sized_relobj<size,big_endian> * relobj,unsigned int input_shndx,unsigned int type,Output_data * od,unsigned int shndx,Address address)1911*a9fa9459Szrj add_local_section(Sized_relobj<size, big_endian>* relobj, 1912*a9fa9459Szrj unsigned int input_shndx, unsigned int type, 1913*a9fa9459Szrj Output_data* od, unsigned int shndx, Address address) 1914*a9fa9459Szrj { 1915*a9fa9459Szrj this->add(od, Output_reloc_type(relobj, input_shndx, type, shndx, 1916*a9fa9459Szrj address, false, false, true, false)); 1917*a9fa9459Szrj } 1918*a9fa9459Szrj 1919*a9fa9459Szrj // A reloc against the STT_SECTION symbol of an output section. 1920*a9fa9459Szrj // OS is the Output_section that the relocation refers to; OD is 1921*a9fa9459Szrj // the Output_data object being relocated. 1922*a9fa9459Szrj 1923*a9fa9459Szrj void add_output_section(Output_section * os,unsigned int type,Output_data * od,Address address)1924*a9fa9459Szrj add_output_section(Output_section* os, unsigned int type, 1925*a9fa9459Szrj Output_data* od, Address address) 1926*a9fa9459Szrj { this->add(od, Output_reloc_type(os, type, od, address, false)); } 1927*a9fa9459Szrj 1928*a9fa9459Szrj void add_output_section(Output_section * os,unsigned int type,Output_data * od,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address)1929*a9fa9459Szrj add_output_section(Output_section* os, unsigned int type, Output_data* od, 1930*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 1931*a9fa9459Szrj unsigned int shndx, Address address) 1932*a9fa9459Szrj { this->add(od, Output_reloc_type(os, type, relobj, shndx, address, false)); } 1933*a9fa9459Szrj 1934*a9fa9459Szrj void add_output_section_generic(Output_section * os,unsigned int type,Output_data * od,uint64_t address,uint64_t addend)1935*a9fa9459Szrj add_output_section_generic(Output_section* os, unsigned int type, 1936*a9fa9459Szrj Output_data* od, uint64_t address, 1937*a9fa9459Szrj uint64_t addend) 1938*a9fa9459Szrj { 1939*a9fa9459Szrj gold_assert(addend == 0); 1940*a9fa9459Szrj this->add(od, Output_reloc_type(os, type, od, 1941*a9fa9459Szrj convert_types<Address, uint64_t>(address), 1942*a9fa9459Szrj false)); 1943*a9fa9459Szrj } 1944*a9fa9459Szrj 1945*a9fa9459Szrj void add_output_section_generic(Output_section * os,unsigned int type,Output_data * od,Relobj * relobj,unsigned int shndx,uint64_t address,uint64_t addend)1946*a9fa9459Szrj add_output_section_generic(Output_section* os, unsigned int type, 1947*a9fa9459Szrj Output_data* od, Relobj* relobj, 1948*a9fa9459Szrj unsigned int shndx, uint64_t address, 1949*a9fa9459Szrj uint64_t addend) 1950*a9fa9459Szrj { 1951*a9fa9459Szrj gold_assert(addend == 0); 1952*a9fa9459Szrj Sized_relobj<size, big_endian>* sized_relobj = 1953*a9fa9459Szrj static_cast<Sized_relobj<size, big_endian>*>(relobj); 1954*a9fa9459Szrj this->add(od, Output_reloc_type(os, type, sized_relobj, shndx, 1955*a9fa9459Szrj convert_types<Address, uint64_t>(address), 1956*a9fa9459Szrj false)); 1957*a9fa9459Szrj } 1958*a9fa9459Szrj 1959*a9fa9459Szrj // As above, but the reloc TYPE is relative 1960*a9fa9459Szrj 1961*a9fa9459Szrj void add_output_section_relative(Output_section * os,unsigned int type,Output_data * od,Address address)1962*a9fa9459Szrj add_output_section_relative(Output_section* os, unsigned int type, 1963*a9fa9459Szrj Output_data* od, Address address) 1964*a9fa9459Szrj { this->add(od, Output_reloc_type(os, type, od, address, true)); } 1965*a9fa9459Szrj 1966*a9fa9459Szrj void add_output_section_relative(Output_section * os,unsigned int type,Output_data * od,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address)1967*a9fa9459Szrj add_output_section_relative(Output_section* os, unsigned int type, 1968*a9fa9459Szrj Output_data* od, 1969*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 1970*a9fa9459Szrj unsigned int shndx, Address address) 1971*a9fa9459Szrj { this->add(od, Output_reloc_type(os, type, relobj, shndx, address, true)); } 1972*a9fa9459Szrj 1973*a9fa9459Szrj // Add an absolute relocation. 1974*a9fa9459Szrj 1975*a9fa9459Szrj void add_absolute(unsigned int type,Output_data * od,Address address)1976*a9fa9459Szrj add_absolute(unsigned int type, Output_data* od, Address address) 1977*a9fa9459Szrj { this->add(od, Output_reloc_type(type, od, address, false)); } 1978*a9fa9459Szrj 1979*a9fa9459Szrj void add_absolute(unsigned int type,Output_data * od,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address)1980*a9fa9459Szrj add_absolute(unsigned int type, Output_data* od, 1981*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 1982*a9fa9459Szrj unsigned int shndx, Address address) 1983*a9fa9459Szrj { this->add(od, Output_reloc_type(type, relobj, shndx, address, false)); } 1984*a9fa9459Szrj 1985*a9fa9459Szrj // Add a relative relocation 1986*a9fa9459Szrj 1987*a9fa9459Szrj void add_relative(unsigned int type,Output_data * od,Address address)1988*a9fa9459Szrj add_relative(unsigned int type, Output_data* od, Address address) 1989*a9fa9459Szrj { this->add(od, Output_reloc_type(type, od, address, true)); } 1990*a9fa9459Szrj 1991*a9fa9459Szrj void add_relative(unsigned int type,Output_data * od,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address)1992*a9fa9459Szrj add_relative(unsigned int type, Output_data* od, 1993*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 1994*a9fa9459Szrj unsigned int shndx, Address address) 1995*a9fa9459Szrj { this->add(od, Output_reloc_type(type, relobj, shndx, address, true)); } 1996*a9fa9459Szrj 1997*a9fa9459Szrj // Add a target specific relocation. A target which calls this must 1998*a9fa9459Szrj // define the reloc_symbol_index and reloc_addend virtual functions. 1999*a9fa9459Szrj 2000*a9fa9459Szrj void add_target_specific(unsigned int type,void * arg,Output_data * od,Address address)2001*a9fa9459Szrj add_target_specific(unsigned int type, void* arg, Output_data* od, 2002*a9fa9459Szrj Address address) 2003*a9fa9459Szrj { this->add(od, Output_reloc_type(type, arg, od, address)); } 2004*a9fa9459Szrj 2005*a9fa9459Szrj void add_target_specific(unsigned int type,void * arg,Output_data * od,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address)2006*a9fa9459Szrj add_target_specific(unsigned int type, void* arg, Output_data* od, 2007*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 2008*a9fa9459Szrj unsigned int shndx, Address address) 2009*a9fa9459Szrj { this->add(od, Output_reloc_type(type, arg, relobj, shndx, address)); } 2010*a9fa9459Szrj }; 2011*a9fa9459Szrj 2012*a9fa9459Szrj // The SHT_RELA version of Output_data_reloc. 2013*a9fa9459Szrj 2014*a9fa9459Szrj template<bool dynamic, int size, bool big_endian> 2015*a9fa9459Szrj class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> 2016*a9fa9459Szrj : public Output_data_reloc_base<elfcpp::SHT_RELA, dynamic, size, big_endian> 2017*a9fa9459Szrj { 2018*a9fa9459Szrj private: 2019*a9fa9459Szrj typedef Output_data_reloc_base<elfcpp::SHT_RELA, dynamic, size, 2020*a9fa9459Szrj big_endian> Base; 2021*a9fa9459Szrj 2022*a9fa9459Szrj public: 2023*a9fa9459Szrj typedef typename Base::Output_reloc_type Output_reloc_type; 2024*a9fa9459Szrj typedef typename Output_reloc_type::Address Address; 2025*a9fa9459Szrj typedef typename Output_reloc_type::Addend Addend; 2026*a9fa9459Szrj Output_data_reloc(bool sr)2027*a9fa9459Szrj Output_data_reloc(bool sr) 2028*a9fa9459Szrj : Output_data_reloc_base<elfcpp::SHT_RELA, dynamic, size, big_endian>(sr) 2029*a9fa9459Szrj { } 2030*a9fa9459Szrj 2031*a9fa9459Szrj // Add a reloc against a global symbol. 2032*a9fa9459Szrj 2033*a9fa9459Szrj void add_global(Symbol * gsym,unsigned int type,Output_data * od,Address address,Addend addend)2034*a9fa9459Szrj add_global(Symbol* gsym, unsigned int type, Output_data* od, 2035*a9fa9459Szrj Address address, Addend addend) 2036*a9fa9459Szrj { 2037*a9fa9459Szrj this->add(od, Output_reloc_type(gsym, type, od, address, addend, 2038*a9fa9459Szrj false, false, false)); 2039*a9fa9459Szrj } 2040*a9fa9459Szrj 2041*a9fa9459Szrj void add_global(Symbol * gsym,unsigned int type,Output_data * od,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address,Addend addend)2042*a9fa9459Szrj add_global(Symbol* gsym, unsigned int type, Output_data* od, 2043*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 2044*a9fa9459Szrj unsigned int shndx, Address address, 2045*a9fa9459Szrj Addend addend) 2046*a9fa9459Szrj { 2047*a9fa9459Szrj this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address, 2048*a9fa9459Szrj addend, false, false, false)); 2049*a9fa9459Szrj } 2050*a9fa9459Szrj 2051*a9fa9459Szrj void add_global_generic(Symbol * gsym,unsigned int type,Output_data * od,uint64_t address,uint64_t addend)2052*a9fa9459Szrj add_global_generic(Symbol* gsym, unsigned int type, Output_data* od, 2053*a9fa9459Szrj uint64_t address, uint64_t addend) 2054*a9fa9459Szrj { 2055*a9fa9459Szrj this->add(od, Output_reloc_type(gsym, type, od, 2056*a9fa9459Szrj convert_types<Address, uint64_t>(address), 2057*a9fa9459Szrj convert_types<Addend, uint64_t>(addend), 2058*a9fa9459Szrj false, false, false)); 2059*a9fa9459Szrj } 2060*a9fa9459Szrj 2061*a9fa9459Szrj void add_global_generic(Symbol * gsym,unsigned int type,Output_data * od,Relobj * relobj,unsigned int shndx,uint64_t address,uint64_t addend)2062*a9fa9459Szrj add_global_generic(Symbol* gsym, unsigned int type, Output_data* od, 2063*a9fa9459Szrj Relobj* relobj, unsigned int shndx, uint64_t address, 2064*a9fa9459Szrj uint64_t addend) 2065*a9fa9459Szrj { 2066*a9fa9459Szrj Sized_relobj<size, big_endian>* sized_relobj = 2067*a9fa9459Szrj static_cast<Sized_relobj<size, big_endian>*>(relobj); 2068*a9fa9459Szrj this->add(od, Output_reloc_type(gsym, type, sized_relobj, shndx, 2069*a9fa9459Szrj convert_types<Address, uint64_t>(address), 2070*a9fa9459Szrj convert_types<Addend, uint64_t>(addend), 2071*a9fa9459Szrj false, false, false)); 2072*a9fa9459Szrj } 2073*a9fa9459Szrj 2074*a9fa9459Szrj // Add a RELATIVE reloc against a global symbol. The final output 2075*a9fa9459Szrj // relocation will not reference the symbol, but we must keep the symbol 2076*a9fa9459Szrj // information long enough to set the addend of the relocation correctly 2077*a9fa9459Szrj // when it is written. 2078*a9fa9459Szrj 2079*a9fa9459Szrj void add_global_relative(Symbol * gsym,unsigned int type,Output_data * od,Address address,Addend addend,bool use_plt_offset)2080*a9fa9459Szrj add_global_relative(Symbol* gsym, unsigned int type, Output_data* od, 2081*a9fa9459Szrj Address address, Addend addend, bool use_plt_offset) 2082*a9fa9459Szrj { 2083*a9fa9459Szrj this->add(od, Output_reloc_type(gsym, type, od, address, addend, true, 2084*a9fa9459Szrj true, use_plt_offset)); 2085*a9fa9459Szrj } 2086*a9fa9459Szrj 2087*a9fa9459Szrj void add_global_relative(Symbol * gsym,unsigned int type,Output_data * od,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address,Addend addend,bool use_plt_offset)2088*a9fa9459Szrj add_global_relative(Symbol* gsym, unsigned int type, Output_data* od, 2089*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 2090*a9fa9459Szrj unsigned int shndx, Address address, Addend addend, 2091*a9fa9459Szrj bool use_plt_offset) 2092*a9fa9459Szrj { 2093*a9fa9459Szrj this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address, 2094*a9fa9459Szrj addend, true, true, use_plt_offset)); 2095*a9fa9459Szrj } 2096*a9fa9459Szrj 2097*a9fa9459Szrj // Add a global relocation which does not use a symbol for the relocation, 2098*a9fa9459Szrj // but which gets its addend from a symbol. 2099*a9fa9459Szrj 2100*a9fa9459Szrj void add_symbolless_global_addend(Symbol * gsym,unsigned int type,Output_data * od,Address address,Addend addend)2101*a9fa9459Szrj add_symbolless_global_addend(Symbol* gsym, unsigned int type, Output_data* od, 2102*a9fa9459Szrj Address address, Addend addend) 2103*a9fa9459Szrj { 2104*a9fa9459Szrj this->add(od, Output_reloc_type(gsym, type, od, address, addend, 2105*a9fa9459Szrj false, true, false)); 2106*a9fa9459Szrj } 2107*a9fa9459Szrj 2108*a9fa9459Szrj void add_symbolless_global_addend(Symbol * gsym,unsigned int type,Output_data * od,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address,Addend addend)2109*a9fa9459Szrj add_symbolless_global_addend(Symbol* gsym, unsigned int type, 2110*a9fa9459Szrj Output_data* od, 2111*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 2112*a9fa9459Szrj unsigned int shndx, Address address, 2113*a9fa9459Szrj Addend addend) 2114*a9fa9459Szrj { 2115*a9fa9459Szrj this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address, 2116*a9fa9459Szrj addend, false, true, false)); 2117*a9fa9459Szrj } 2118*a9fa9459Szrj 2119*a9fa9459Szrj // Add a reloc against a local symbol. 2120*a9fa9459Szrj 2121*a9fa9459Szrj void add_local(Sized_relobj<size,big_endian> * relobj,unsigned int local_sym_index,unsigned int type,Output_data * od,Address address,Addend addend)2122*a9fa9459Szrj add_local(Sized_relobj<size, big_endian>* relobj, 2123*a9fa9459Szrj unsigned int local_sym_index, unsigned int type, 2124*a9fa9459Szrj Output_data* od, Address address, Addend addend) 2125*a9fa9459Szrj { 2126*a9fa9459Szrj this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address, 2127*a9fa9459Szrj addend, false, false, false, false)); 2128*a9fa9459Szrj } 2129*a9fa9459Szrj 2130*a9fa9459Szrj void add_local(Sized_relobj<size,big_endian> * relobj,unsigned int local_sym_index,unsigned int type,Output_data * od,unsigned int shndx,Address address,Addend addend)2131*a9fa9459Szrj add_local(Sized_relobj<size, big_endian>* relobj, 2132*a9fa9459Szrj unsigned int local_sym_index, unsigned int type, 2133*a9fa9459Szrj Output_data* od, unsigned int shndx, Address address, 2134*a9fa9459Szrj Addend addend) 2135*a9fa9459Szrj { 2136*a9fa9459Szrj this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, 2137*a9fa9459Szrj address, addend, false, false, false, 2138*a9fa9459Szrj false)); 2139*a9fa9459Szrj } 2140*a9fa9459Szrj 2141*a9fa9459Szrj void add_local_generic(Relobj * relobj,unsigned int local_sym_index,unsigned int type,Output_data * od,uint64_t address,uint64_t addend)2142*a9fa9459Szrj add_local_generic(Relobj* relobj, unsigned int local_sym_index, 2143*a9fa9459Szrj unsigned int type, Output_data* od, uint64_t address, 2144*a9fa9459Szrj uint64_t addend) 2145*a9fa9459Szrj { 2146*a9fa9459Szrj Sized_relobj<size, big_endian>* sized_relobj = 2147*a9fa9459Szrj static_cast<Sized_relobj<size, big_endian> *>(relobj); 2148*a9fa9459Szrj this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, od, 2149*a9fa9459Szrj convert_types<Address, uint64_t>(address), 2150*a9fa9459Szrj convert_types<Addend, uint64_t>(addend), 2151*a9fa9459Szrj false, false, false, false)); 2152*a9fa9459Szrj } 2153*a9fa9459Szrj 2154*a9fa9459Szrj void add_local_generic(Relobj * relobj,unsigned int local_sym_index,unsigned int type,Output_data * od,unsigned int shndx,uint64_t address,uint64_t addend)2155*a9fa9459Szrj add_local_generic(Relobj* relobj, unsigned int local_sym_index, 2156*a9fa9459Szrj unsigned int type, Output_data* od, unsigned int shndx, 2157*a9fa9459Szrj uint64_t address, uint64_t addend) 2158*a9fa9459Szrj { 2159*a9fa9459Szrj Sized_relobj<size, big_endian>* sized_relobj = 2160*a9fa9459Szrj static_cast<Sized_relobj<size, big_endian>*>(relobj); 2161*a9fa9459Szrj this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, shndx, 2162*a9fa9459Szrj convert_types<Address, uint64_t>(address), 2163*a9fa9459Szrj convert_types<Addend, uint64_t>(addend), 2164*a9fa9459Szrj false, false, false, false)); 2165*a9fa9459Szrj } 2166*a9fa9459Szrj 2167*a9fa9459Szrj // Add a RELATIVE reloc against a local symbol. 2168*a9fa9459Szrj 2169*a9fa9459Szrj void add_local_relative(Sized_relobj<size,big_endian> * relobj,unsigned int local_sym_index,unsigned int type,Output_data * od,Address address,Addend addend,bool use_plt_offset)2170*a9fa9459Szrj add_local_relative(Sized_relobj<size, big_endian>* relobj, 2171*a9fa9459Szrj unsigned int local_sym_index, unsigned int type, 2172*a9fa9459Szrj Output_data* od, Address address, Addend addend, 2173*a9fa9459Szrj bool use_plt_offset) 2174*a9fa9459Szrj { 2175*a9fa9459Szrj this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address, 2176*a9fa9459Szrj addend, true, true, false, 2177*a9fa9459Szrj use_plt_offset)); 2178*a9fa9459Szrj } 2179*a9fa9459Szrj 2180*a9fa9459Szrj void add_local_relative(Sized_relobj<size,big_endian> * relobj,unsigned int local_sym_index,unsigned int type,Output_data * od,unsigned int shndx,Address address,Addend addend,bool use_plt_offset)2181*a9fa9459Szrj add_local_relative(Sized_relobj<size, big_endian>* relobj, 2182*a9fa9459Szrj unsigned int local_sym_index, unsigned int type, 2183*a9fa9459Szrj Output_data* od, unsigned int shndx, Address address, 2184*a9fa9459Szrj Addend addend, bool use_plt_offset) 2185*a9fa9459Szrj { 2186*a9fa9459Szrj this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, 2187*a9fa9459Szrj address, addend, true, true, false, 2188*a9fa9459Szrj use_plt_offset)); 2189*a9fa9459Szrj } 2190*a9fa9459Szrj 2191*a9fa9459Szrj // Add a local relocation which does not use a symbol for the relocation, 2192*a9fa9459Szrj // but which gets it's addend from a symbol. 2193*a9fa9459Szrj 2194*a9fa9459Szrj void add_symbolless_local_addend(Sized_relobj<size,big_endian> * relobj,unsigned int local_sym_index,unsigned int type,Output_data * od,Address address,Addend addend)2195*a9fa9459Szrj add_symbolless_local_addend(Sized_relobj<size, big_endian>* relobj, 2196*a9fa9459Szrj unsigned int local_sym_index, unsigned int type, 2197*a9fa9459Szrj Output_data* od, Address address, Addend addend) 2198*a9fa9459Szrj { 2199*a9fa9459Szrj this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address, 2200*a9fa9459Szrj addend, false, true, false, false)); 2201*a9fa9459Szrj } 2202*a9fa9459Szrj 2203*a9fa9459Szrj void add_symbolless_local_addend(Sized_relobj<size,big_endian> * relobj,unsigned int local_sym_index,unsigned int type,Output_data * od,unsigned int shndx,Address address,Addend addend)2204*a9fa9459Szrj add_symbolless_local_addend(Sized_relobj<size, big_endian>* relobj, 2205*a9fa9459Szrj unsigned int local_sym_index, unsigned int type, 2206*a9fa9459Szrj Output_data* od, unsigned int shndx, 2207*a9fa9459Szrj Address address, Addend addend) 2208*a9fa9459Szrj { 2209*a9fa9459Szrj this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, 2210*a9fa9459Szrj address, addend, false, true, false, 2211*a9fa9459Szrj false)); 2212*a9fa9459Szrj } 2213*a9fa9459Szrj 2214*a9fa9459Szrj // Add a reloc against a local section symbol. This will be 2215*a9fa9459Szrj // converted into a reloc against the STT_SECTION symbol of the 2216*a9fa9459Szrj // output section. 2217*a9fa9459Szrj 2218*a9fa9459Szrj void add_local_section(Sized_relobj<size,big_endian> * relobj,unsigned int input_shndx,unsigned int type,Output_data * od,Address address,Addend addend)2219*a9fa9459Szrj add_local_section(Sized_relobj<size, big_endian>* relobj, 2220*a9fa9459Szrj unsigned int input_shndx, unsigned int type, 2221*a9fa9459Szrj Output_data* od, Address address, Addend addend) 2222*a9fa9459Szrj { 2223*a9fa9459Szrj this->add(od, Output_reloc_type(relobj, input_shndx, type, od, address, 2224*a9fa9459Szrj addend, false, false, true, false)); 2225*a9fa9459Szrj } 2226*a9fa9459Szrj 2227*a9fa9459Szrj void add_local_section(Sized_relobj<size,big_endian> * relobj,unsigned int input_shndx,unsigned int type,Output_data * od,unsigned int shndx,Address address,Addend addend)2228*a9fa9459Szrj add_local_section(Sized_relobj<size, big_endian>* relobj, 2229*a9fa9459Szrj unsigned int input_shndx, unsigned int type, 2230*a9fa9459Szrj Output_data* od, unsigned int shndx, Address address, 2231*a9fa9459Szrj Addend addend) 2232*a9fa9459Szrj { 2233*a9fa9459Szrj this->add(od, Output_reloc_type(relobj, input_shndx, type, shndx, 2234*a9fa9459Szrj address, addend, false, false, true, 2235*a9fa9459Szrj false)); 2236*a9fa9459Szrj } 2237*a9fa9459Szrj 2238*a9fa9459Szrj // A reloc against the STT_SECTION symbol of an output section. 2239*a9fa9459Szrj 2240*a9fa9459Szrj void add_output_section(Output_section * os,unsigned int type,Output_data * od,Address address,Addend addend)2241*a9fa9459Szrj add_output_section(Output_section* os, unsigned int type, Output_data* od, 2242*a9fa9459Szrj Address address, Addend addend) 2243*a9fa9459Szrj { this->add(od, Output_reloc_type(os, type, od, address, addend, false)); } 2244*a9fa9459Szrj 2245*a9fa9459Szrj void add_output_section(Output_section * os,unsigned int type,Output_data * od,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address,Addend addend)2246*a9fa9459Szrj add_output_section(Output_section* os, unsigned int type, Output_data* od, 2247*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 2248*a9fa9459Szrj unsigned int shndx, Address address, Addend addend) 2249*a9fa9459Szrj { 2250*a9fa9459Szrj this->add(od, Output_reloc_type(os, type, relobj, shndx, address, 2251*a9fa9459Szrj addend, false)); 2252*a9fa9459Szrj } 2253*a9fa9459Szrj 2254*a9fa9459Szrj void add_output_section_generic(Output_section * os,unsigned int type,Output_data * od,uint64_t address,uint64_t addend)2255*a9fa9459Szrj add_output_section_generic(Output_section* os, unsigned int type, 2256*a9fa9459Szrj Output_data* od, uint64_t address, 2257*a9fa9459Szrj uint64_t addend) 2258*a9fa9459Szrj { 2259*a9fa9459Szrj this->add(od, Output_reloc_type(os, type, od, 2260*a9fa9459Szrj convert_types<Address, uint64_t>(address), 2261*a9fa9459Szrj convert_types<Addend, uint64_t>(addend), 2262*a9fa9459Szrj false)); 2263*a9fa9459Szrj } 2264*a9fa9459Szrj 2265*a9fa9459Szrj void add_output_section_generic(Output_section * os,unsigned int type,Output_data * od,Relobj * relobj,unsigned int shndx,uint64_t address,uint64_t addend)2266*a9fa9459Szrj add_output_section_generic(Output_section* os, unsigned int type, 2267*a9fa9459Szrj Output_data* od, Relobj* relobj, 2268*a9fa9459Szrj unsigned int shndx, uint64_t address, 2269*a9fa9459Szrj uint64_t addend) 2270*a9fa9459Szrj { 2271*a9fa9459Szrj Sized_relobj<size, big_endian>* sized_relobj = 2272*a9fa9459Szrj static_cast<Sized_relobj<size, big_endian>*>(relobj); 2273*a9fa9459Szrj this->add(od, Output_reloc_type(os, type, sized_relobj, shndx, 2274*a9fa9459Szrj convert_types<Address, uint64_t>(address), 2275*a9fa9459Szrj convert_types<Addend, uint64_t>(addend), 2276*a9fa9459Szrj false)); 2277*a9fa9459Szrj } 2278*a9fa9459Szrj 2279*a9fa9459Szrj // As above, but the reloc TYPE is relative 2280*a9fa9459Szrj 2281*a9fa9459Szrj void add_output_section_relative(Output_section * os,unsigned int type,Output_data * od,Address address,Addend addend)2282*a9fa9459Szrj add_output_section_relative(Output_section* os, unsigned int type, 2283*a9fa9459Szrj Output_data* od, Address address, Addend addend) 2284*a9fa9459Szrj { this->add(od, Output_reloc_type(os, type, od, address, addend, true)); } 2285*a9fa9459Szrj 2286*a9fa9459Szrj void add_output_section_relative(Output_section * os,unsigned int type,Output_data * od,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address,Addend addend)2287*a9fa9459Szrj add_output_section_relative(Output_section* os, unsigned int type, 2288*a9fa9459Szrj Output_data* od, 2289*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 2290*a9fa9459Szrj unsigned int shndx, Address address, 2291*a9fa9459Szrj Addend addend) 2292*a9fa9459Szrj { 2293*a9fa9459Szrj this->add(od, Output_reloc_type(os, type, relobj, shndx, 2294*a9fa9459Szrj address, addend, true)); 2295*a9fa9459Szrj } 2296*a9fa9459Szrj 2297*a9fa9459Szrj // Add an absolute relocation. 2298*a9fa9459Szrj 2299*a9fa9459Szrj void add_absolute(unsigned int type,Output_data * od,Address address,Addend addend)2300*a9fa9459Szrj add_absolute(unsigned int type, Output_data* od, Address address, 2301*a9fa9459Szrj Addend addend) 2302*a9fa9459Szrj { this->add(od, Output_reloc_type(type, od, address, addend, false)); } 2303*a9fa9459Szrj 2304*a9fa9459Szrj void add_absolute(unsigned int type,Output_data * od,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address,Addend addend)2305*a9fa9459Szrj add_absolute(unsigned int type, Output_data* od, 2306*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 2307*a9fa9459Szrj unsigned int shndx, Address address, Addend addend) 2308*a9fa9459Szrj { 2309*a9fa9459Szrj this->add(od, Output_reloc_type(type, relobj, shndx, address, addend, 2310*a9fa9459Szrj false)); 2311*a9fa9459Szrj } 2312*a9fa9459Szrj 2313*a9fa9459Szrj // Add a relative relocation 2314*a9fa9459Szrj 2315*a9fa9459Szrj void add_relative(unsigned int type,Output_data * od,Address address,Addend addend)2316*a9fa9459Szrj add_relative(unsigned int type, Output_data* od, Address address, 2317*a9fa9459Szrj Addend addend) 2318*a9fa9459Szrj { this->add(od, Output_reloc_type(type, od, address, addend, true)); } 2319*a9fa9459Szrj 2320*a9fa9459Szrj void add_relative(unsigned int type,Output_data * od,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address,Addend addend)2321*a9fa9459Szrj add_relative(unsigned int type, Output_data* od, 2322*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 2323*a9fa9459Szrj unsigned int shndx, Address address, Addend addend) 2324*a9fa9459Szrj { 2325*a9fa9459Szrj this->add(od, Output_reloc_type(type, relobj, shndx, address, addend, 2326*a9fa9459Szrj true)); 2327*a9fa9459Szrj } 2328*a9fa9459Szrj 2329*a9fa9459Szrj // Add a target specific relocation. A target which calls this must 2330*a9fa9459Szrj // define the reloc_symbol_index and reloc_addend virtual functions. 2331*a9fa9459Szrj 2332*a9fa9459Szrj void add_target_specific(unsigned int type,void * arg,Output_data * od,Address address,Addend addend)2333*a9fa9459Szrj add_target_specific(unsigned int type, void* arg, Output_data* od, 2334*a9fa9459Szrj Address address, Addend addend) 2335*a9fa9459Szrj { this->add(od, Output_reloc_type(type, arg, od, address, addend)); } 2336*a9fa9459Szrj 2337*a9fa9459Szrj void add_target_specific(unsigned int type,void * arg,Output_data * od,Sized_relobj<size,big_endian> * relobj,unsigned int shndx,Address address,Addend addend)2338*a9fa9459Szrj add_target_specific(unsigned int type, void* arg, Output_data* od, 2339*a9fa9459Szrj Sized_relobj<size, big_endian>* relobj, 2340*a9fa9459Szrj unsigned int shndx, Address address, Addend addend) 2341*a9fa9459Szrj { 2342*a9fa9459Szrj this->add(od, Output_reloc_type(type, arg, relobj, shndx, address, 2343*a9fa9459Szrj addend)); 2344*a9fa9459Szrj } 2345*a9fa9459Szrj }; 2346*a9fa9459Szrj 2347*a9fa9459Szrj // Output_relocatable_relocs represents a relocation section in a 2348*a9fa9459Szrj // relocatable link. The actual data is written out in the target 2349*a9fa9459Szrj // hook relocate_relocs. This just saves space for it. 2350*a9fa9459Szrj 2351*a9fa9459Szrj template<int sh_type, int size, bool big_endian> 2352*a9fa9459Szrj class Output_relocatable_relocs : public Output_section_data 2353*a9fa9459Szrj { 2354*a9fa9459Szrj public: Output_relocatable_relocs(Relocatable_relocs * rr)2355*a9fa9459Szrj Output_relocatable_relocs(Relocatable_relocs* rr) 2356*a9fa9459Szrj : Output_section_data(Output_data::default_alignment_for_size(size)), 2357*a9fa9459Szrj rr_(rr) 2358*a9fa9459Szrj { } 2359*a9fa9459Szrj 2360*a9fa9459Szrj void 2361*a9fa9459Szrj set_final_data_size(); 2362*a9fa9459Szrj 2363*a9fa9459Szrj // Write out the data. There is nothing to do here. 2364*a9fa9459Szrj void do_write(Output_file *)2365*a9fa9459Szrj do_write(Output_file*) 2366*a9fa9459Szrj { } 2367*a9fa9459Szrj 2368*a9fa9459Szrj // Write to a map file. 2369*a9fa9459Szrj void do_print_to_mapfile(Mapfile * mapfile)2370*a9fa9459Szrj do_print_to_mapfile(Mapfile* mapfile) const 2371*a9fa9459Szrj { mapfile->print_output_data(this, _("** relocs")); } 2372*a9fa9459Szrj 2373*a9fa9459Szrj private: 2374*a9fa9459Szrj // The relocs associated with this input section. 2375*a9fa9459Szrj Relocatable_relocs* rr_; 2376*a9fa9459Szrj }; 2377*a9fa9459Szrj 2378*a9fa9459Szrj // Handle a GROUP section. 2379*a9fa9459Szrj 2380*a9fa9459Szrj template<int size, bool big_endian> 2381*a9fa9459Szrj class Output_data_group : public Output_section_data 2382*a9fa9459Szrj { 2383*a9fa9459Szrj public: 2384*a9fa9459Szrj // The constructor clears *INPUT_SHNDXES. 2385*a9fa9459Szrj Output_data_group(Sized_relobj_file<size, big_endian>* relobj, 2386*a9fa9459Szrj section_size_type entry_count, 2387*a9fa9459Szrj elfcpp::Elf_Word flags, 2388*a9fa9459Szrj std::vector<unsigned int>* input_shndxes); 2389*a9fa9459Szrj 2390*a9fa9459Szrj void 2391*a9fa9459Szrj do_write(Output_file*); 2392*a9fa9459Szrj 2393*a9fa9459Szrj // Write to a map file. 2394*a9fa9459Szrj void do_print_to_mapfile(Mapfile * mapfile)2395*a9fa9459Szrj do_print_to_mapfile(Mapfile* mapfile) const 2396*a9fa9459Szrj { mapfile->print_output_data(this, _("** group")); } 2397*a9fa9459Szrj 2398*a9fa9459Szrj // Set final data size. 2399*a9fa9459Szrj void set_final_data_size()2400*a9fa9459Szrj set_final_data_size() 2401*a9fa9459Szrj { this->set_data_size((this->input_shndxes_.size() + 1) * 4); } 2402*a9fa9459Szrj 2403*a9fa9459Szrj private: 2404*a9fa9459Szrj // The input object. 2405*a9fa9459Szrj Sized_relobj_file<size, big_endian>* relobj_; 2406*a9fa9459Szrj // The group flag word. 2407*a9fa9459Szrj elfcpp::Elf_Word flags_; 2408*a9fa9459Szrj // The section indexes of the input sections in this group. 2409*a9fa9459Szrj std::vector<unsigned int> input_shndxes_; 2410*a9fa9459Szrj }; 2411*a9fa9459Szrj 2412*a9fa9459Szrj // Output_data_got is used to manage a GOT. Each entry in the GOT is 2413*a9fa9459Szrj // for one symbol--either a global symbol or a local symbol in an 2414*a9fa9459Szrj // object. The target specific code adds entries to the GOT as 2415*a9fa9459Szrj // needed. The GOT_SIZE template parameter is the size in bits of a 2416*a9fa9459Szrj // GOT entry, typically 32 or 64. 2417*a9fa9459Szrj 2418*a9fa9459Szrj class Output_data_got_base : public Output_section_data_build 2419*a9fa9459Szrj { 2420*a9fa9459Szrj public: Output_data_got_base(uint64_t align)2421*a9fa9459Szrj Output_data_got_base(uint64_t align) 2422*a9fa9459Szrj : Output_section_data_build(align) 2423*a9fa9459Szrj { } 2424*a9fa9459Szrj Output_data_got_base(off_t data_size,uint64_t align)2425*a9fa9459Szrj Output_data_got_base(off_t data_size, uint64_t align) 2426*a9fa9459Szrj : Output_section_data_build(data_size, align) 2427*a9fa9459Szrj { } 2428*a9fa9459Szrj 2429*a9fa9459Szrj // Reserve the slot at index I in the GOT. 2430*a9fa9459Szrj void reserve_slot(unsigned int i)2431*a9fa9459Szrj reserve_slot(unsigned int i) 2432*a9fa9459Szrj { this->do_reserve_slot(i); } 2433*a9fa9459Szrj 2434*a9fa9459Szrj protected: 2435*a9fa9459Szrj // Reserve the slot at index I in the GOT. 2436*a9fa9459Szrj virtual void 2437*a9fa9459Szrj do_reserve_slot(unsigned int i) = 0; 2438*a9fa9459Szrj }; 2439*a9fa9459Szrj 2440*a9fa9459Szrj template<int got_size, bool big_endian> 2441*a9fa9459Szrj class Output_data_got : public Output_data_got_base 2442*a9fa9459Szrj { 2443*a9fa9459Szrj public: 2444*a9fa9459Szrj typedef typename elfcpp::Elf_types<got_size>::Elf_Addr Valtype; 2445*a9fa9459Szrj Output_data_got()2446*a9fa9459Szrj Output_data_got() 2447*a9fa9459Szrj : Output_data_got_base(Output_data::default_alignment_for_size(got_size)), 2448*a9fa9459Szrj entries_(), free_list_() 2449*a9fa9459Szrj { } 2450*a9fa9459Szrj Output_data_got(off_t data_size)2451*a9fa9459Szrj Output_data_got(off_t data_size) 2452*a9fa9459Szrj : Output_data_got_base(data_size, 2453*a9fa9459Szrj Output_data::default_alignment_for_size(got_size)), 2454*a9fa9459Szrj entries_(), free_list_() 2455*a9fa9459Szrj { 2456*a9fa9459Szrj // For an incremental update, we have an existing GOT section. 2457*a9fa9459Szrj // Initialize the list of entries and the free list. 2458*a9fa9459Szrj this->entries_.resize(data_size / (got_size / 8)); 2459*a9fa9459Szrj this->free_list_.init(data_size, false); 2460*a9fa9459Szrj } 2461*a9fa9459Szrj 2462*a9fa9459Szrj // Add an entry for a global symbol to the GOT. Return true if this 2463*a9fa9459Szrj // is a new GOT entry, false if the symbol was already in the GOT. 2464*a9fa9459Szrj bool 2465*a9fa9459Szrj add_global(Symbol* gsym, unsigned int got_type); 2466*a9fa9459Szrj 2467*a9fa9459Szrj // Like add_global, but use the PLT offset of the global symbol if 2468*a9fa9459Szrj // it has one. 2469*a9fa9459Szrj bool 2470*a9fa9459Szrj add_global_plt(Symbol* gsym, unsigned int got_type); 2471*a9fa9459Szrj 2472*a9fa9459Szrj // Like add_global, but for a TLS symbol where the value will be 2473*a9fa9459Szrj // offset using Target::tls_offset_for_global. 2474*a9fa9459Szrj bool add_global_tls(Symbol * gsym,unsigned int got_type)2475*a9fa9459Szrj add_global_tls(Symbol* gsym, unsigned int got_type) 2476*a9fa9459Szrj { return add_global_plt(gsym, got_type); } 2477*a9fa9459Szrj 2478*a9fa9459Szrj // Add an entry for a global symbol to the GOT, and add a dynamic 2479*a9fa9459Szrj // relocation of type R_TYPE for the GOT entry. 2480*a9fa9459Szrj void 2481*a9fa9459Szrj add_global_with_rel(Symbol* gsym, unsigned int got_type, 2482*a9fa9459Szrj Output_data_reloc_generic* rel_dyn, unsigned int r_type); 2483*a9fa9459Szrj 2484*a9fa9459Szrj // Add a pair of entries for a global symbol to the GOT, and add 2485*a9fa9459Szrj // dynamic relocations of type R_TYPE_1 and R_TYPE_2, respectively. 2486*a9fa9459Szrj void 2487*a9fa9459Szrj add_global_pair_with_rel(Symbol* gsym, unsigned int got_type, 2488*a9fa9459Szrj Output_data_reloc_generic* rel_dyn, 2489*a9fa9459Szrj unsigned int r_type_1, unsigned int r_type_2); 2490*a9fa9459Szrj 2491*a9fa9459Szrj // Add an entry for a local symbol to the GOT. This returns true if 2492*a9fa9459Szrj // this is a new GOT entry, false if the symbol already has a GOT 2493*a9fa9459Szrj // entry. 2494*a9fa9459Szrj bool 2495*a9fa9459Szrj add_local(Relobj* object, unsigned int sym_index, unsigned int got_type); 2496*a9fa9459Szrj 2497*a9fa9459Szrj // Add an entry for a local symbol plus ADDEND to the GOT. This returns 2498*a9fa9459Szrj // true if this is a new GOT entry, false if the symbol already has a GOT 2499*a9fa9459Szrj // entry. 2500*a9fa9459Szrj bool 2501*a9fa9459Szrj add_local(Relobj* object, unsigned int sym_index, unsigned int got_type, 2502*a9fa9459Szrj uint64_t addend); 2503*a9fa9459Szrj 2504*a9fa9459Szrj // Like add_local, but use the PLT offset of the local symbol if it 2505*a9fa9459Szrj // has one. 2506*a9fa9459Szrj bool 2507*a9fa9459Szrj add_local_plt(Relobj* object, unsigned int sym_index, unsigned int got_type); 2508*a9fa9459Szrj 2509*a9fa9459Szrj // Like add_local, but for a TLS symbol where the value will be 2510*a9fa9459Szrj // offset using Target::tls_offset_for_local. 2511*a9fa9459Szrj bool add_local_tls(Relobj * object,unsigned int sym_index,unsigned int got_type)2512*a9fa9459Szrj add_local_tls(Relobj* object, unsigned int sym_index, unsigned int got_type) 2513*a9fa9459Szrj { return add_local_plt(object, sym_index, got_type); } 2514*a9fa9459Szrj 2515*a9fa9459Szrj // Add an entry for a local symbol to the GOT, and add a dynamic 2516*a9fa9459Szrj // relocation of type R_TYPE for the GOT entry. 2517*a9fa9459Szrj void 2518*a9fa9459Szrj add_local_with_rel(Relobj* object, unsigned int sym_index, 2519*a9fa9459Szrj unsigned int got_type, Output_data_reloc_generic* rel_dyn, 2520*a9fa9459Szrj unsigned int r_type); 2521*a9fa9459Szrj 2522*a9fa9459Szrj // Add an entry for a local symbol plus ADDEND to the GOT, and add a dynamic 2523*a9fa9459Szrj // relocation of type R_TYPE for the GOT entry. 2524*a9fa9459Szrj void 2525*a9fa9459Szrj add_local_with_rel(Relobj* object, unsigned int sym_index, 2526*a9fa9459Szrj unsigned int got_type, Output_data_reloc_generic* rel_dyn, 2527*a9fa9459Szrj unsigned int r_type, uint64_t addend); 2528*a9fa9459Szrj 2529*a9fa9459Szrj // Add a pair of entries for a local symbol to the GOT, and add 2530*a9fa9459Szrj // a dynamic relocation of type R_TYPE using the section symbol of 2531*a9fa9459Szrj // the output section to which input section SHNDX maps, on the first. 2532*a9fa9459Szrj // The first got entry will have a value of zero, the second the 2533*a9fa9459Szrj // value of the local symbol. 2534*a9fa9459Szrj void 2535*a9fa9459Szrj add_local_pair_with_rel(Relobj* object, unsigned int sym_index, 2536*a9fa9459Szrj unsigned int shndx, unsigned int got_type, 2537*a9fa9459Szrj Output_data_reloc_generic* rel_dyn, 2538*a9fa9459Szrj unsigned int r_type); 2539*a9fa9459Szrj 2540*a9fa9459Szrj // Add a pair of entries for a local symbol plus ADDEND to the GOT, and add 2541*a9fa9459Szrj // a dynamic relocation of type R_TYPE using the section symbol of 2542*a9fa9459Szrj // the output section to which input section SHNDX maps, on the first. 2543*a9fa9459Szrj // The first got entry will have a value of zero, the second the 2544*a9fa9459Szrj // value of the local symbol. 2545*a9fa9459Szrj void 2546*a9fa9459Szrj add_local_pair_with_rel(Relobj* object, unsigned int sym_index, 2547*a9fa9459Szrj unsigned int shndx, unsigned int got_type, 2548*a9fa9459Szrj Output_data_reloc_generic* rel_dyn, 2549*a9fa9459Szrj unsigned int r_type, uint64_t addend); 2550*a9fa9459Szrj 2551*a9fa9459Szrj // Add a pair of entries for a local symbol to the GOT, and add 2552*a9fa9459Szrj // a dynamic relocation of type R_TYPE using STN_UNDEF on the first. 2553*a9fa9459Szrj // The first got entry will have a value of zero, the second the 2554*a9fa9459Szrj // value of the local symbol offset by Target::tls_offset_for_local. 2555*a9fa9459Szrj void 2556*a9fa9459Szrj add_local_tls_pair(Relobj* object, unsigned int sym_index, 2557*a9fa9459Szrj unsigned int got_type, 2558*a9fa9459Szrj Output_data_reloc_generic* rel_dyn, 2559*a9fa9459Szrj unsigned int r_type); 2560*a9fa9459Szrj 2561*a9fa9459Szrj // Add a constant to the GOT. This returns the offset of the new 2562*a9fa9459Szrj // entry from the start of the GOT. 2563*a9fa9459Szrj unsigned int add_constant(Valtype constant)2564*a9fa9459Szrj add_constant(Valtype constant) 2565*a9fa9459Szrj { return this->add_got_entry(Got_entry(constant)); } 2566*a9fa9459Szrj 2567*a9fa9459Szrj // Add a pair of constants to the GOT. This returns the offset of 2568*a9fa9459Szrj // the new entry from the start of the GOT. 2569*a9fa9459Szrj unsigned int add_constant_pair(Valtype c1,Valtype c2)2570*a9fa9459Szrj add_constant_pair(Valtype c1, Valtype c2) 2571*a9fa9459Szrj { return this->add_got_entry_pair(Got_entry(c1), Got_entry(c2)); } 2572*a9fa9459Szrj 2573*a9fa9459Szrj // Replace GOT entry I with a new constant. 2574*a9fa9459Szrj void replace_constant(unsigned int i,Valtype constant)2575*a9fa9459Szrj replace_constant(unsigned int i, Valtype constant) 2576*a9fa9459Szrj { 2577*a9fa9459Szrj this->replace_got_entry(i, Got_entry(constant)); 2578*a9fa9459Szrj } 2579*a9fa9459Szrj 2580*a9fa9459Szrj // Reserve a slot in the GOT for a local symbol. 2581*a9fa9459Szrj void 2582*a9fa9459Szrj reserve_local(unsigned int i, Relobj* object, unsigned int sym_index, 2583*a9fa9459Szrj unsigned int got_type); 2584*a9fa9459Szrj 2585*a9fa9459Szrj // Reserve a slot in the GOT for a global symbol. 2586*a9fa9459Szrj void 2587*a9fa9459Szrj reserve_global(unsigned int i, Symbol* gsym, unsigned int got_type); 2588*a9fa9459Szrj 2589*a9fa9459Szrj protected: 2590*a9fa9459Szrj // Write out the GOT table. 2591*a9fa9459Szrj void 2592*a9fa9459Szrj do_write(Output_file*); 2593*a9fa9459Szrj 2594*a9fa9459Szrj // Write to a map file. 2595*a9fa9459Szrj void do_print_to_mapfile(Mapfile * mapfile)2596*a9fa9459Szrj do_print_to_mapfile(Mapfile* mapfile) const 2597*a9fa9459Szrj { mapfile->print_output_data(this, _("** GOT")); } 2598*a9fa9459Szrj 2599*a9fa9459Szrj // Reserve the slot at index I in the GOT. 2600*a9fa9459Szrj virtual void do_reserve_slot(unsigned int i)2601*a9fa9459Szrj do_reserve_slot(unsigned int i) 2602*a9fa9459Szrj { this->free_list_.remove(i * got_size / 8, (i + 1) * got_size / 8); } 2603*a9fa9459Szrj 2604*a9fa9459Szrj // Return the number of words in the GOT. 2605*a9fa9459Szrj unsigned int num_entries()2606*a9fa9459Szrj num_entries () const 2607*a9fa9459Szrj { return this->entries_.size(); } 2608*a9fa9459Szrj 2609*a9fa9459Szrj // Return the offset into the GOT of GOT entry I. 2610*a9fa9459Szrj unsigned int got_offset(unsigned int i)2611*a9fa9459Szrj got_offset(unsigned int i) const 2612*a9fa9459Szrj { return i * (got_size / 8); } 2613*a9fa9459Szrj 2614*a9fa9459Szrj private: 2615*a9fa9459Szrj // This POD class holds a single GOT entry. 2616*a9fa9459Szrj class Got_entry 2617*a9fa9459Szrj { 2618*a9fa9459Szrj public: 2619*a9fa9459Szrj // Create a zero entry. Got_entry()2620*a9fa9459Szrj Got_entry() 2621*a9fa9459Szrj : local_sym_index_(RESERVED_CODE), use_plt_or_tls_offset_(false), 2622*a9fa9459Szrj addend_(0) 2623*a9fa9459Szrj { this->u_.constant = 0; } 2624*a9fa9459Szrj 2625*a9fa9459Szrj // Create a global symbol entry. Got_entry(Symbol * gsym,bool use_plt_or_tls_offset)2626*a9fa9459Szrj Got_entry(Symbol* gsym, bool use_plt_or_tls_offset) 2627*a9fa9459Szrj : local_sym_index_(GSYM_CODE), 2628*a9fa9459Szrj use_plt_or_tls_offset_(use_plt_or_tls_offset), addend_(0) 2629*a9fa9459Szrj { this->u_.gsym = gsym; } 2630*a9fa9459Szrj 2631*a9fa9459Szrj // Create a local symbol entry. Got_entry(Relobj * object,unsigned int local_sym_index,bool use_plt_or_tls_offset)2632*a9fa9459Szrj Got_entry(Relobj* object, unsigned int local_sym_index, 2633*a9fa9459Szrj bool use_plt_or_tls_offset) 2634*a9fa9459Szrj : local_sym_index_(local_sym_index), 2635*a9fa9459Szrj use_plt_or_tls_offset_(use_plt_or_tls_offset), addend_(0) 2636*a9fa9459Szrj { 2637*a9fa9459Szrj gold_assert(local_sym_index != GSYM_CODE 2638*a9fa9459Szrj && local_sym_index != CONSTANT_CODE 2639*a9fa9459Szrj && local_sym_index != RESERVED_CODE 2640*a9fa9459Szrj && local_sym_index == this->local_sym_index_); 2641*a9fa9459Szrj this->u_.object = object; 2642*a9fa9459Szrj } 2643*a9fa9459Szrj 2644*a9fa9459Szrj // Create a local symbol entry plus addend. Got_entry(Relobj * object,unsigned int local_sym_index,bool use_plt_or_tls_offset,uint64_t addend)2645*a9fa9459Szrj Got_entry(Relobj* object, unsigned int local_sym_index, 2646*a9fa9459Szrj bool use_plt_or_tls_offset, uint64_t addend) 2647*a9fa9459Szrj : local_sym_index_(local_sym_index), 2648*a9fa9459Szrj use_plt_or_tls_offset_(use_plt_or_tls_offset), addend_(addend) 2649*a9fa9459Szrj { 2650*a9fa9459Szrj gold_assert(local_sym_index != GSYM_CODE 2651*a9fa9459Szrj && local_sym_index != CONSTANT_CODE 2652*a9fa9459Szrj && local_sym_index != RESERVED_CODE 2653*a9fa9459Szrj && local_sym_index == this->local_sym_index_); 2654*a9fa9459Szrj this->u_.object = object; 2655*a9fa9459Szrj } 2656*a9fa9459Szrj 2657*a9fa9459Szrj // Create a constant entry. The constant is a host value--it will 2658*a9fa9459Szrj // be swapped, if necessary, when it is written out. Got_entry(Valtype constant)2659*a9fa9459Szrj explicit Got_entry(Valtype constant) 2660*a9fa9459Szrj : local_sym_index_(CONSTANT_CODE), use_plt_or_tls_offset_(false) 2661*a9fa9459Szrj { this->u_.constant = constant; } 2662*a9fa9459Szrj 2663*a9fa9459Szrj // Write the GOT entry to an output view. 2664*a9fa9459Szrj void 2665*a9fa9459Szrj write(unsigned int got_indx, unsigned char* pov) const; 2666*a9fa9459Szrj 2667*a9fa9459Szrj private: 2668*a9fa9459Szrj enum 2669*a9fa9459Szrj { 2670*a9fa9459Szrj GSYM_CODE = 0x7fffffff, 2671*a9fa9459Szrj CONSTANT_CODE = 0x7ffffffe, 2672*a9fa9459Szrj RESERVED_CODE = 0x7ffffffd 2673*a9fa9459Szrj }; 2674*a9fa9459Szrj 2675*a9fa9459Szrj union 2676*a9fa9459Szrj { 2677*a9fa9459Szrj // For a local symbol, the object. 2678*a9fa9459Szrj Relobj* object; 2679*a9fa9459Szrj // For a global symbol, the symbol. 2680*a9fa9459Szrj Symbol* gsym; 2681*a9fa9459Szrj // For a constant, the constant. 2682*a9fa9459Szrj Valtype constant; 2683*a9fa9459Szrj } u_; 2684*a9fa9459Szrj // For a local symbol, the local symbol index. This is GSYM_CODE 2685*a9fa9459Szrj // for a global symbol, or CONSTANT_CODE for a constant. 2686*a9fa9459Szrj unsigned int local_sym_index_ : 31; 2687*a9fa9459Szrj // Whether to use the PLT offset of the symbol if it has one. 2688*a9fa9459Szrj // For TLS symbols, whether to offset the symbol value. 2689*a9fa9459Szrj bool use_plt_or_tls_offset_ : 1; 2690*a9fa9459Szrj // The addend. 2691*a9fa9459Szrj uint64_t addend_; 2692*a9fa9459Szrj }; 2693*a9fa9459Szrj 2694*a9fa9459Szrj typedef std::vector<Got_entry> Got_entries; 2695*a9fa9459Szrj 2696*a9fa9459Szrj // Create a new GOT entry and return its offset. 2697*a9fa9459Szrj unsigned int 2698*a9fa9459Szrj add_got_entry(Got_entry got_entry); 2699*a9fa9459Szrj 2700*a9fa9459Szrj // Create a pair of new GOT entries and return the offset of the first. 2701*a9fa9459Szrj unsigned int 2702*a9fa9459Szrj add_got_entry_pair(Got_entry got_entry_1, Got_entry got_entry_2); 2703*a9fa9459Szrj 2704*a9fa9459Szrj // Replace GOT entry I with a new value. 2705*a9fa9459Szrj void 2706*a9fa9459Szrj replace_got_entry(unsigned int i, Got_entry got_entry); 2707*a9fa9459Szrj 2708*a9fa9459Szrj // Return the offset into the GOT of the last entry added. 2709*a9fa9459Szrj unsigned int last_got_offset()2710*a9fa9459Szrj last_got_offset() const 2711*a9fa9459Szrj { return this->got_offset(this->num_entries() - 1); } 2712*a9fa9459Szrj 2713*a9fa9459Szrj // Set the size of the section. 2714*a9fa9459Szrj void set_got_size()2715*a9fa9459Szrj set_got_size() 2716*a9fa9459Szrj { this->set_current_data_size(this->got_offset(this->num_entries())); } 2717*a9fa9459Szrj 2718*a9fa9459Szrj // The list of GOT entries. 2719*a9fa9459Szrj Got_entries entries_; 2720*a9fa9459Szrj 2721*a9fa9459Szrj // List of available regions within the section, for incremental 2722*a9fa9459Szrj // update links. 2723*a9fa9459Szrj Free_list free_list_; 2724*a9fa9459Szrj }; 2725*a9fa9459Szrj 2726*a9fa9459Szrj // Output_data_dynamic is used to hold the data in SHT_DYNAMIC 2727*a9fa9459Szrj // section. 2728*a9fa9459Szrj 2729*a9fa9459Szrj class Output_data_dynamic : public Output_section_data 2730*a9fa9459Szrj { 2731*a9fa9459Szrj public: Output_data_dynamic(Stringpool * pool)2732*a9fa9459Szrj Output_data_dynamic(Stringpool* pool) 2733*a9fa9459Szrj : Output_section_data(Output_data::default_alignment()), 2734*a9fa9459Szrj entries_(), pool_(pool) 2735*a9fa9459Szrj { } 2736*a9fa9459Szrj 2737*a9fa9459Szrj // Add a new dynamic entry with a fixed numeric value. 2738*a9fa9459Szrj void add_constant(elfcpp::DT tag,unsigned int val)2739*a9fa9459Szrj add_constant(elfcpp::DT tag, unsigned int val) 2740*a9fa9459Szrj { this->add_entry(Dynamic_entry(tag, val)); } 2741*a9fa9459Szrj 2742*a9fa9459Szrj // Add a new dynamic entry with the address of output data. 2743*a9fa9459Szrj void add_section_address(elfcpp::DT tag,const Output_data * od)2744*a9fa9459Szrj add_section_address(elfcpp::DT tag, const Output_data* od) 2745*a9fa9459Szrj { this->add_entry(Dynamic_entry(tag, od, false)); } 2746*a9fa9459Szrj 2747*a9fa9459Szrj // Add a new dynamic entry with the address of output data 2748*a9fa9459Szrj // plus a constant offset. 2749*a9fa9459Szrj void add_section_plus_offset(elfcpp::DT tag,const Output_data * od,unsigned int offset)2750*a9fa9459Szrj add_section_plus_offset(elfcpp::DT tag, const Output_data* od, 2751*a9fa9459Szrj unsigned int offset) 2752*a9fa9459Szrj { this->add_entry(Dynamic_entry(tag, od, offset)); } 2753*a9fa9459Szrj 2754*a9fa9459Szrj // Add a new dynamic entry with the size of output data. 2755*a9fa9459Szrj void add_section_size(elfcpp::DT tag,const Output_data * od)2756*a9fa9459Szrj add_section_size(elfcpp::DT tag, const Output_data* od) 2757*a9fa9459Szrj { this->add_entry(Dynamic_entry(tag, od, true)); } 2758*a9fa9459Szrj 2759*a9fa9459Szrj // Add a new dynamic entry with the total size of two output datas. 2760*a9fa9459Szrj void add_section_size(elfcpp::DT tag,const Output_data * od,const Output_data * od2)2761*a9fa9459Szrj add_section_size(elfcpp::DT tag, const Output_data* od, 2762*a9fa9459Szrj const Output_data* od2) 2763*a9fa9459Szrj { this->add_entry(Dynamic_entry(tag, od, od2)); } 2764*a9fa9459Szrj 2765*a9fa9459Szrj // Add a new dynamic entry with the address of a symbol. 2766*a9fa9459Szrj void add_symbol(elfcpp::DT tag,const Symbol * sym)2767*a9fa9459Szrj add_symbol(elfcpp::DT tag, const Symbol* sym) 2768*a9fa9459Szrj { this->add_entry(Dynamic_entry(tag, sym)); } 2769*a9fa9459Szrj 2770*a9fa9459Szrj // Add a new dynamic entry with a string. 2771*a9fa9459Szrj void add_string(elfcpp::DT tag,const char * str)2772*a9fa9459Szrj add_string(elfcpp::DT tag, const char* str) 2773*a9fa9459Szrj { this->add_entry(Dynamic_entry(tag, this->pool_->add(str, true, NULL))); } 2774*a9fa9459Szrj 2775*a9fa9459Szrj void add_string(elfcpp::DT tag,const std::string & str)2776*a9fa9459Szrj add_string(elfcpp::DT tag, const std::string& str) 2777*a9fa9459Szrj { this->add_string(tag, str.c_str()); } 2778*a9fa9459Szrj 2779*a9fa9459Szrj // Add a new dynamic entry with custom value. 2780*a9fa9459Szrj void add_custom(elfcpp::DT tag)2781*a9fa9459Szrj add_custom(elfcpp::DT tag) 2782*a9fa9459Szrj { this->add_entry(Dynamic_entry(tag)); } 2783*a9fa9459Szrj 2784*a9fa9459Szrj // Get a dynamic entry offset. 2785*a9fa9459Szrj unsigned int 2786*a9fa9459Szrj get_entry_offset(elfcpp::DT tag) const; 2787*a9fa9459Szrj 2788*a9fa9459Szrj protected: 2789*a9fa9459Szrj // Adjust the output section to set the entry size. 2790*a9fa9459Szrj void 2791*a9fa9459Szrj do_adjust_output_section(Output_section*); 2792*a9fa9459Szrj 2793*a9fa9459Szrj // Set the final data size. 2794*a9fa9459Szrj void 2795*a9fa9459Szrj set_final_data_size(); 2796*a9fa9459Szrj 2797*a9fa9459Szrj // Write out the dynamic entries. 2798*a9fa9459Szrj void 2799*a9fa9459Szrj do_write(Output_file*); 2800*a9fa9459Szrj 2801*a9fa9459Szrj // Write to a map file. 2802*a9fa9459Szrj void do_print_to_mapfile(Mapfile * mapfile)2803*a9fa9459Szrj do_print_to_mapfile(Mapfile* mapfile) const 2804*a9fa9459Szrj { mapfile->print_output_data(this, _("** dynamic")); } 2805*a9fa9459Szrj 2806*a9fa9459Szrj private: 2807*a9fa9459Szrj // This POD class holds a single dynamic entry. 2808*a9fa9459Szrj class Dynamic_entry 2809*a9fa9459Szrj { 2810*a9fa9459Szrj public: 2811*a9fa9459Szrj // Create an entry with a fixed numeric value. Dynamic_entry(elfcpp::DT tag,unsigned int val)2812*a9fa9459Szrj Dynamic_entry(elfcpp::DT tag, unsigned int val) 2813*a9fa9459Szrj : tag_(tag), offset_(DYNAMIC_NUMBER) 2814*a9fa9459Szrj { this->u_.val = val; } 2815*a9fa9459Szrj 2816*a9fa9459Szrj // Create an entry with the size or address of a section. Dynamic_entry(elfcpp::DT tag,const Output_data * od,bool section_size)2817*a9fa9459Szrj Dynamic_entry(elfcpp::DT tag, const Output_data* od, bool section_size) 2818*a9fa9459Szrj : tag_(tag), 2819*a9fa9459Szrj offset_(section_size 2820*a9fa9459Szrj ? DYNAMIC_SECTION_SIZE 2821*a9fa9459Szrj : DYNAMIC_SECTION_ADDRESS) 2822*a9fa9459Szrj { 2823*a9fa9459Szrj this->u_.od = od; 2824*a9fa9459Szrj this->od2 = NULL; 2825*a9fa9459Szrj } 2826*a9fa9459Szrj 2827*a9fa9459Szrj // Create an entry with the size of two sections. Dynamic_entry(elfcpp::DT tag,const Output_data * od,const Output_data * od2)2828*a9fa9459Szrj Dynamic_entry(elfcpp::DT tag, const Output_data* od, const Output_data* od2) 2829*a9fa9459Szrj : tag_(tag), 2830*a9fa9459Szrj offset_(DYNAMIC_SECTION_SIZE) 2831*a9fa9459Szrj { 2832*a9fa9459Szrj this->u_.od = od; 2833*a9fa9459Szrj this->od2 = od2; 2834*a9fa9459Szrj } 2835*a9fa9459Szrj 2836*a9fa9459Szrj // Create an entry with the address of a section plus a constant offset. Dynamic_entry(elfcpp::DT tag,const Output_data * od,unsigned int offset)2837*a9fa9459Szrj Dynamic_entry(elfcpp::DT tag, const Output_data* od, unsigned int offset) 2838*a9fa9459Szrj : tag_(tag), 2839*a9fa9459Szrj offset_(offset) 2840*a9fa9459Szrj { this->u_.od = od; } 2841*a9fa9459Szrj 2842*a9fa9459Szrj // Create an entry with the address of a symbol. Dynamic_entry(elfcpp::DT tag,const Symbol * sym)2843*a9fa9459Szrj Dynamic_entry(elfcpp::DT tag, const Symbol* sym) 2844*a9fa9459Szrj : tag_(tag), offset_(DYNAMIC_SYMBOL) 2845*a9fa9459Szrj { this->u_.sym = sym; } 2846*a9fa9459Szrj 2847*a9fa9459Szrj // Create an entry with a string. Dynamic_entry(elfcpp::DT tag,const char * str)2848*a9fa9459Szrj Dynamic_entry(elfcpp::DT tag, const char* str) 2849*a9fa9459Szrj : tag_(tag), offset_(DYNAMIC_STRING) 2850*a9fa9459Szrj { this->u_.str = str; } 2851*a9fa9459Szrj 2852*a9fa9459Szrj // Create an entry with a custom value. Dynamic_entry(elfcpp::DT tag)2853*a9fa9459Szrj Dynamic_entry(elfcpp::DT tag) 2854*a9fa9459Szrj : tag_(tag), offset_(DYNAMIC_CUSTOM) 2855*a9fa9459Szrj { } 2856*a9fa9459Szrj 2857*a9fa9459Szrj // Return the tag of this entry. 2858*a9fa9459Szrj elfcpp::DT tag()2859*a9fa9459Szrj tag() const 2860*a9fa9459Szrj { return this->tag_; } 2861*a9fa9459Szrj 2862*a9fa9459Szrj // Write the dynamic entry to an output view. 2863*a9fa9459Szrj template<int size, bool big_endian> 2864*a9fa9459Szrj void 2865*a9fa9459Szrj write(unsigned char* pov, const Stringpool*) const; 2866*a9fa9459Szrj 2867*a9fa9459Szrj private: 2868*a9fa9459Szrj // Classification is encoded in the OFFSET field. 2869*a9fa9459Szrj enum Classification 2870*a9fa9459Szrj { 2871*a9fa9459Szrj // Section address. 2872*a9fa9459Szrj DYNAMIC_SECTION_ADDRESS = 0, 2873*a9fa9459Szrj // Number. 2874*a9fa9459Szrj DYNAMIC_NUMBER = -1U, 2875*a9fa9459Szrj // Section size. 2876*a9fa9459Szrj DYNAMIC_SECTION_SIZE = -2U, 2877*a9fa9459Szrj // Symbol adress. 2878*a9fa9459Szrj DYNAMIC_SYMBOL = -3U, 2879*a9fa9459Szrj // String. 2880*a9fa9459Szrj DYNAMIC_STRING = -4U, 2881*a9fa9459Szrj // Custom value. 2882*a9fa9459Szrj DYNAMIC_CUSTOM = -5U 2883*a9fa9459Szrj // Any other value indicates a section address plus OFFSET. 2884*a9fa9459Szrj }; 2885*a9fa9459Szrj 2886*a9fa9459Szrj union 2887*a9fa9459Szrj { 2888*a9fa9459Szrj // For DYNAMIC_NUMBER. 2889*a9fa9459Szrj unsigned int val; 2890*a9fa9459Szrj // For DYNAMIC_SECTION_SIZE and section address plus OFFSET. 2891*a9fa9459Szrj const Output_data* od; 2892*a9fa9459Szrj // For DYNAMIC_SYMBOL. 2893*a9fa9459Szrj const Symbol* sym; 2894*a9fa9459Szrj // For DYNAMIC_STRING. 2895*a9fa9459Szrj const char* str; 2896*a9fa9459Szrj } u_; 2897*a9fa9459Szrj // For DYNAMIC_SYMBOL with two sections. 2898*a9fa9459Szrj const Output_data* od2; 2899*a9fa9459Szrj // The dynamic tag. 2900*a9fa9459Szrj elfcpp::DT tag_; 2901*a9fa9459Szrj // The type of entry (Classification) or offset within a section. 2902*a9fa9459Szrj unsigned int offset_; 2903*a9fa9459Szrj }; 2904*a9fa9459Szrj 2905*a9fa9459Szrj // Add an entry to the list. 2906*a9fa9459Szrj void add_entry(const Dynamic_entry & entry)2907*a9fa9459Szrj add_entry(const Dynamic_entry& entry) 2908*a9fa9459Szrj { this->entries_.push_back(entry); } 2909*a9fa9459Szrj 2910*a9fa9459Szrj // Sized version of write function. 2911*a9fa9459Szrj template<int size, bool big_endian> 2912*a9fa9459Szrj void 2913*a9fa9459Szrj sized_write(Output_file* of); 2914*a9fa9459Szrj 2915*a9fa9459Szrj // The type of the list of entries. 2916*a9fa9459Szrj typedef std::vector<Dynamic_entry> Dynamic_entries; 2917*a9fa9459Szrj 2918*a9fa9459Szrj // The entries. 2919*a9fa9459Szrj Dynamic_entries entries_; 2920*a9fa9459Szrj // The pool used for strings. 2921*a9fa9459Szrj Stringpool* pool_; 2922*a9fa9459Szrj }; 2923*a9fa9459Szrj 2924*a9fa9459Szrj // Output_symtab_xindex is used to handle SHT_SYMTAB_SHNDX sections, 2925*a9fa9459Szrj // which may be required if the object file has more than 2926*a9fa9459Szrj // SHN_LORESERVE sections. 2927*a9fa9459Szrj 2928*a9fa9459Szrj class Output_symtab_xindex : public Output_section_data 2929*a9fa9459Szrj { 2930*a9fa9459Szrj public: Output_symtab_xindex(size_t symcount)2931*a9fa9459Szrj Output_symtab_xindex(size_t symcount) 2932*a9fa9459Szrj : Output_section_data(symcount * 4, 4, true), 2933*a9fa9459Szrj entries_() 2934*a9fa9459Szrj { } 2935*a9fa9459Szrj 2936*a9fa9459Szrj // Add an entry: symbol number SYMNDX has section SHNDX. 2937*a9fa9459Szrj void add(unsigned int symndx,unsigned int shndx)2938*a9fa9459Szrj add(unsigned int symndx, unsigned int shndx) 2939*a9fa9459Szrj { this->entries_.push_back(std::make_pair(symndx, shndx)); } 2940*a9fa9459Szrj 2941*a9fa9459Szrj protected: 2942*a9fa9459Szrj void 2943*a9fa9459Szrj do_write(Output_file*); 2944*a9fa9459Szrj 2945*a9fa9459Szrj // Write to a map file. 2946*a9fa9459Szrj void do_print_to_mapfile(Mapfile * mapfile)2947*a9fa9459Szrj do_print_to_mapfile(Mapfile* mapfile) const 2948*a9fa9459Szrj { mapfile->print_output_data(this, _("** symtab xindex")); } 2949*a9fa9459Szrj 2950*a9fa9459Szrj private: 2951*a9fa9459Szrj template<bool big_endian> 2952*a9fa9459Szrj void 2953*a9fa9459Szrj endian_do_write(unsigned char*); 2954*a9fa9459Szrj 2955*a9fa9459Szrj // It is likely that most symbols will not require entries. Rather 2956*a9fa9459Szrj // than keep a vector for all symbols, we keep pairs of symbol index 2957*a9fa9459Szrj // and section index. 2958*a9fa9459Szrj typedef std::vector<std::pair<unsigned int, unsigned int> > Xindex_entries; 2959*a9fa9459Szrj 2960*a9fa9459Szrj // The entries we need. 2961*a9fa9459Szrj Xindex_entries entries_; 2962*a9fa9459Szrj }; 2963*a9fa9459Szrj 2964*a9fa9459Szrj // A relaxed input section. 2965*a9fa9459Szrj class Output_relaxed_input_section : public Output_section_data_build 2966*a9fa9459Szrj { 2967*a9fa9459Szrj public: 2968*a9fa9459Szrj // We would like to call relobj->section_addralign(shndx) to get the 2969*a9fa9459Szrj // alignment but we do not want the constructor to fail. So callers 2970*a9fa9459Szrj // are repsonsible for ensuring that. Output_relaxed_input_section(Relobj * relobj,unsigned int shndx,uint64_t addralign)2971*a9fa9459Szrj Output_relaxed_input_section(Relobj* relobj, unsigned int shndx, 2972*a9fa9459Szrj uint64_t addralign) 2973*a9fa9459Szrj : Output_section_data_build(addralign), relobj_(relobj), shndx_(shndx) 2974*a9fa9459Szrj { } 2975*a9fa9459Szrj 2976*a9fa9459Szrj // Return the Relobj of this relaxed input section. 2977*a9fa9459Szrj Relobj* relobj()2978*a9fa9459Szrj relobj() const 2979*a9fa9459Szrj { return this->relobj_; } 2980*a9fa9459Szrj 2981*a9fa9459Szrj // Return the section index of this relaxed input section. 2982*a9fa9459Szrj unsigned int shndx()2983*a9fa9459Szrj shndx() const 2984*a9fa9459Szrj { return this->shndx_; } 2985*a9fa9459Szrj 2986*a9fa9459Szrj protected: 2987*a9fa9459Szrj void set_relobj(Relobj * relobj)2988*a9fa9459Szrj set_relobj(Relobj* relobj) 2989*a9fa9459Szrj { this->relobj_ = relobj; } 2990*a9fa9459Szrj 2991*a9fa9459Szrj void set_shndx(unsigned int shndx)2992*a9fa9459Szrj set_shndx(unsigned int shndx) 2993*a9fa9459Szrj { this->shndx_ = shndx; } 2994*a9fa9459Szrj 2995*a9fa9459Szrj private: 2996*a9fa9459Szrj Relobj* relobj_; 2997*a9fa9459Szrj unsigned int shndx_; 2998*a9fa9459Szrj }; 2999*a9fa9459Szrj 3000*a9fa9459Szrj // This class describes properties of merge data sections. It is used 3001*a9fa9459Szrj // as a key type for maps. 3002*a9fa9459Szrj class Merge_section_properties 3003*a9fa9459Szrj { 3004*a9fa9459Szrj public: Merge_section_properties(bool is_string,uint64_t entsize,uint64_t addralign)3005*a9fa9459Szrj Merge_section_properties(bool is_string, uint64_t entsize, 3006*a9fa9459Szrj uint64_t addralign) 3007*a9fa9459Szrj : is_string_(is_string), entsize_(entsize), addralign_(addralign) 3008*a9fa9459Szrj { } 3009*a9fa9459Szrj 3010*a9fa9459Szrj // Whether this equals to another Merge_section_properties MSP. 3011*a9fa9459Szrj bool eq(const Merge_section_properties & msp)3012*a9fa9459Szrj eq(const Merge_section_properties& msp) const 3013*a9fa9459Szrj { 3014*a9fa9459Szrj return ((this->is_string_ == msp.is_string_) 3015*a9fa9459Szrj && (this->entsize_ == msp.entsize_) 3016*a9fa9459Szrj && (this->addralign_ == msp.addralign_)); 3017*a9fa9459Szrj } 3018*a9fa9459Szrj 3019*a9fa9459Szrj // Compute a hash value for this using 64-bit FNV-1a hash. 3020*a9fa9459Szrj size_t hash_value()3021*a9fa9459Szrj hash_value() const 3022*a9fa9459Szrj { 3023*a9fa9459Szrj uint64_t h = 14695981039346656037ULL; // FNV offset basis. 3024*a9fa9459Szrj uint64_t prime = 1099511628211ULL; 3025*a9fa9459Szrj h = (h ^ static_cast<uint64_t>(this->is_string_)) * prime; 3026*a9fa9459Szrj h = (h ^ static_cast<uint64_t>(this->entsize_)) * prime; 3027*a9fa9459Szrj h = (h ^ static_cast<uint64_t>(this->addralign_)) * prime; 3028*a9fa9459Szrj return h; 3029*a9fa9459Szrj } 3030*a9fa9459Szrj 3031*a9fa9459Szrj // Functors for associative containers. 3032*a9fa9459Szrj struct equal_to 3033*a9fa9459Szrj { 3034*a9fa9459Szrj bool operatorequal_to3035*a9fa9459Szrj operator()(const Merge_section_properties& msp1, 3036*a9fa9459Szrj const Merge_section_properties& msp2) const 3037*a9fa9459Szrj { return msp1.eq(msp2); } 3038*a9fa9459Szrj }; 3039*a9fa9459Szrj 3040*a9fa9459Szrj struct hash 3041*a9fa9459Szrj { 3042*a9fa9459Szrj size_t operatorhash3043*a9fa9459Szrj operator()(const Merge_section_properties& msp) const 3044*a9fa9459Szrj { return msp.hash_value(); } 3045*a9fa9459Szrj }; 3046*a9fa9459Szrj 3047*a9fa9459Szrj private: 3048*a9fa9459Szrj // Whether this merge data section is for strings. 3049*a9fa9459Szrj bool is_string_; 3050*a9fa9459Szrj // Entsize of this merge data section. 3051*a9fa9459Szrj uint64_t entsize_; 3052*a9fa9459Szrj // Address alignment. 3053*a9fa9459Szrj uint64_t addralign_; 3054*a9fa9459Szrj }; 3055*a9fa9459Szrj 3056*a9fa9459Szrj // This class is used to speed up look up of special input sections in an 3057*a9fa9459Szrj // Output_section. 3058*a9fa9459Szrj 3059*a9fa9459Szrj class Output_section_lookup_maps 3060*a9fa9459Szrj { 3061*a9fa9459Szrj public: Output_section_lookup_maps()3062*a9fa9459Szrj Output_section_lookup_maps() 3063*a9fa9459Szrj : is_valid_(true), merge_sections_by_properties_(), 3064*a9fa9459Szrj relaxed_input_sections_by_id_() 3065*a9fa9459Szrj { } 3066*a9fa9459Szrj 3067*a9fa9459Szrj // Whether the maps are valid. 3068*a9fa9459Szrj bool is_valid()3069*a9fa9459Szrj is_valid() const 3070*a9fa9459Szrj { return this->is_valid_; } 3071*a9fa9459Szrj 3072*a9fa9459Szrj // Invalidate the maps. 3073*a9fa9459Szrj void invalidate()3074*a9fa9459Szrj invalidate() 3075*a9fa9459Szrj { this->is_valid_ = false; } 3076*a9fa9459Szrj 3077*a9fa9459Szrj // Clear the maps. 3078*a9fa9459Szrj void clear()3079*a9fa9459Szrj clear() 3080*a9fa9459Szrj { 3081*a9fa9459Szrj this->merge_sections_by_properties_.clear(); 3082*a9fa9459Szrj this->relaxed_input_sections_by_id_.clear(); 3083*a9fa9459Szrj // A cleared map is valid. 3084*a9fa9459Szrj this->is_valid_ = true; 3085*a9fa9459Szrj } 3086*a9fa9459Szrj 3087*a9fa9459Szrj // Find a merge section by merge section properties. Return NULL if none 3088*a9fa9459Szrj // is found. 3089*a9fa9459Szrj Output_merge_base* find_merge_section(const Merge_section_properties & msp)3090*a9fa9459Szrj find_merge_section(const Merge_section_properties& msp) const 3091*a9fa9459Szrj { 3092*a9fa9459Szrj gold_assert(this->is_valid_); 3093*a9fa9459Szrj Merge_sections_by_properties::const_iterator p = 3094*a9fa9459Szrj this->merge_sections_by_properties_.find(msp); 3095*a9fa9459Szrj return p != this->merge_sections_by_properties_.end() ? p->second : NULL; 3096*a9fa9459Szrj } 3097*a9fa9459Szrj 3098*a9fa9459Szrj // Add a merge section pointed by POMB with properties MSP. 3099*a9fa9459Szrj void add_merge_section(const Merge_section_properties & msp,Output_merge_base * pomb)3100*a9fa9459Szrj add_merge_section(const Merge_section_properties& msp, 3101*a9fa9459Szrj Output_merge_base* pomb) 3102*a9fa9459Szrj { 3103*a9fa9459Szrj std::pair<Merge_section_properties, Output_merge_base*> value(msp, pomb); 3104*a9fa9459Szrj std::pair<Merge_sections_by_properties::iterator, bool> result = 3105*a9fa9459Szrj this->merge_sections_by_properties_.insert(value); 3106*a9fa9459Szrj gold_assert(result.second); 3107*a9fa9459Szrj } 3108*a9fa9459Szrj 3109*a9fa9459Szrj // Find a relaxed input section of OBJECT with index SHNDX. 3110*a9fa9459Szrj Output_relaxed_input_section* find_relaxed_input_section(const Relobj * object,unsigned int shndx)3111*a9fa9459Szrj find_relaxed_input_section(const Relobj* object, unsigned int shndx) const 3112*a9fa9459Szrj { 3113*a9fa9459Szrj gold_assert(this->is_valid_); 3114*a9fa9459Szrj Relaxed_input_sections_by_id::const_iterator p = 3115*a9fa9459Szrj this->relaxed_input_sections_by_id_.find(Const_section_id(object, shndx)); 3116*a9fa9459Szrj return p != this->relaxed_input_sections_by_id_.end() ? p->second : NULL; 3117*a9fa9459Szrj } 3118*a9fa9459Szrj 3119*a9fa9459Szrj // Add a relaxed input section pointed by POMB and whose original input 3120*a9fa9459Szrj // section is in OBJECT with index SHNDX. 3121*a9fa9459Szrj void add_relaxed_input_section(const Relobj * relobj,unsigned int shndx,Output_relaxed_input_section * poris)3122*a9fa9459Szrj add_relaxed_input_section(const Relobj* relobj, unsigned int shndx, 3123*a9fa9459Szrj Output_relaxed_input_section* poris) 3124*a9fa9459Szrj { 3125*a9fa9459Szrj Const_section_id csid(relobj, shndx); 3126*a9fa9459Szrj std::pair<Const_section_id, Output_relaxed_input_section*> 3127*a9fa9459Szrj value(csid, poris); 3128*a9fa9459Szrj std::pair<Relaxed_input_sections_by_id::iterator, bool> result = 3129*a9fa9459Szrj this->relaxed_input_sections_by_id_.insert(value); 3130*a9fa9459Szrj gold_assert(result.second); 3131*a9fa9459Szrj } 3132*a9fa9459Szrj 3133*a9fa9459Szrj private: 3134*a9fa9459Szrj typedef Unordered_map<Merge_section_properties, Output_merge_base*, 3135*a9fa9459Szrj Merge_section_properties::hash, 3136*a9fa9459Szrj Merge_section_properties::equal_to> 3137*a9fa9459Szrj Merge_sections_by_properties; 3138*a9fa9459Szrj 3139*a9fa9459Szrj typedef Unordered_map<Const_section_id, Output_relaxed_input_section*, 3140*a9fa9459Szrj Const_section_id_hash> 3141*a9fa9459Szrj Relaxed_input_sections_by_id; 3142*a9fa9459Szrj 3143*a9fa9459Szrj // Whether this is valid 3144*a9fa9459Szrj bool is_valid_; 3145*a9fa9459Szrj // Merge sections by merge section properties. 3146*a9fa9459Szrj Merge_sections_by_properties merge_sections_by_properties_; 3147*a9fa9459Szrj // Relaxed sections by section IDs. 3148*a9fa9459Szrj Relaxed_input_sections_by_id relaxed_input_sections_by_id_; 3149*a9fa9459Szrj }; 3150*a9fa9459Szrj 3151*a9fa9459Szrj // This abstract base class defines the interface for the 3152*a9fa9459Szrj // types of methods used to fill free space left in an output 3153*a9fa9459Szrj // section during an incremental link. These methods are used 3154*a9fa9459Szrj // to insert dummy compilation units into debug info so that 3155*a9fa9459Szrj // debug info consumers can scan the debug info serially. 3156*a9fa9459Szrj 3157*a9fa9459Szrj class Output_fill 3158*a9fa9459Szrj { 3159*a9fa9459Szrj public: Output_fill()3160*a9fa9459Szrj Output_fill() 3161*a9fa9459Szrj : is_big_endian_(parameters->target().is_big_endian()) 3162*a9fa9459Szrj { } 3163*a9fa9459Szrj 3164*a9fa9459Szrj virtual ~Output_fill()3165*a9fa9459Szrj ~Output_fill() 3166*a9fa9459Szrj { } 3167*a9fa9459Szrj 3168*a9fa9459Szrj // Return the smallest size chunk of free space that can be 3169*a9fa9459Szrj // filled with a dummy compilation unit. 3170*a9fa9459Szrj size_t minimum_hole_size()3171*a9fa9459Szrj minimum_hole_size() const 3172*a9fa9459Szrj { return this->do_minimum_hole_size(); } 3173*a9fa9459Szrj 3174*a9fa9459Szrj // Write a fill pattern of length LEN at offset OFF in the file. 3175*a9fa9459Szrj void write(Output_file * of,off_t off,size_t len)3176*a9fa9459Szrj write(Output_file* of, off_t off, size_t len) const 3177*a9fa9459Szrj { this->do_write(of, off, len); } 3178*a9fa9459Szrj 3179*a9fa9459Szrj protected: 3180*a9fa9459Szrj virtual size_t 3181*a9fa9459Szrj do_minimum_hole_size() const = 0; 3182*a9fa9459Szrj 3183*a9fa9459Szrj virtual void 3184*a9fa9459Szrj do_write(Output_file* of, off_t off, size_t len) const = 0; 3185*a9fa9459Szrj 3186*a9fa9459Szrj bool is_big_endian()3187*a9fa9459Szrj is_big_endian() const 3188*a9fa9459Szrj { return this->is_big_endian_; } 3189*a9fa9459Szrj 3190*a9fa9459Szrj private: 3191*a9fa9459Szrj bool is_big_endian_; 3192*a9fa9459Szrj }; 3193*a9fa9459Szrj 3194*a9fa9459Szrj // Fill method that introduces a dummy compilation unit in 3195*a9fa9459Szrj // a .debug_info or .debug_types section. 3196*a9fa9459Szrj 3197*a9fa9459Szrj class Output_fill_debug_info : public Output_fill 3198*a9fa9459Szrj { 3199*a9fa9459Szrj public: Output_fill_debug_info(bool is_debug_types)3200*a9fa9459Szrj Output_fill_debug_info(bool is_debug_types) 3201*a9fa9459Szrj : is_debug_types_(is_debug_types) 3202*a9fa9459Szrj { } 3203*a9fa9459Szrj 3204*a9fa9459Szrj protected: 3205*a9fa9459Szrj virtual size_t 3206*a9fa9459Szrj do_minimum_hole_size() const; 3207*a9fa9459Szrj 3208*a9fa9459Szrj virtual void 3209*a9fa9459Szrj do_write(Output_file* of, off_t off, size_t len) const; 3210*a9fa9459Szrj 3211*a9fa9459Szrj private: 3212*a9fa9459Szrj // Version of the header. 3213*a9fa9459Szrj static const int version = 4; 3214*a9fa9459Szrj // True if this is a .debug_types section. 3215*a9fa9459Szrj bool is_debug_types_; 3216*a9fa9459Szrj }; 3217*a9fa9459Szrj 3218*a9fa9459Szrj // Fill method that introduces a dummy compilation unit in 3219*a9fa9459Szrj // a .debug_line section. 3220*a9fa9459Szrj 3221*a9fa9459Szrj class Output_fill_debug_line : public Output_fill 3222*a9fa9459Szrj { 3223*a9fa9459Szrj public: Output_fill_debug_line()3224*a9fa9459Szrj Output_fill_debug_line() 3225*a9fa9459Szrj { } 3226*a9fa9459Szrj 3227*a9fa9459Szrj protected: 3228*a9fa9459Szrj virtual size_t 3229*a9fa9459Szrj do_minimum_hole_size() const; 3230*a9fa9459Szrj 3231*a9fa9459Szrj virtual void 3232*a9fa9459Szrj do_write(Output_file* of, off_t off, size_t len) const; 3233*a9fa9459Szrj 3234*a9fa9459Szrj private: 3235*a9fa9459Szrj // Version of the header. We write a DWARF-3 header because it's smaller 3236*a9fa9459Szrj // and many tools have not yet been updated to understand the DWARF-4 header. 3237*a9fa9459Szrj static const int version = 3; 3238*a9fa9459Szrj // Length of the portion of the header that follows the header_length 3239*a9fa9459Szrj // field. This includes the following fields: 3240*a9fa9459Szrj // minimum_instruction_length, default_is_stmt, line_base, line_range, 3241*a9fa9459Szrj // opcode_base, standard_opcode_lengths[], include_directories, filenames. 3242*a9fa9459Szrj // The standard_opcode_lengths array is 12 bytes long, and the 3243*a9fa9459Szrj // include_directories and filenames fields each contain only a single 3244*a9fa9459Szrj // null byte. 3245*a9fa9459Szrj static const size_t header_length = 19; 3246*a9fa9459Szrj }; 3247*a9fa9459Szrj 3248*a9fa9459Szrj // An output section. We don't expect to have too many output 3249*a9fa9459Szrj // sections, so we don't bother to do a template on the size. 3250*a9fa9459Szrj 3251*a9fa9459Szrj class Output_section : public Output_data 3252*a9fa9459Szrj { 3253*a9fa9459Szrj public: 3254*a9fa9459Szrj // Create an output section, giving the name, type, and flags. 3255*a9fa9459Szrj Output_section(const char* name, elfcpp::Elf_Word, elfcpp::Elf_Xword); 3256*a9fa9459Szrj virtual ~Output_section(); 3257*a9fa9459Szrj 3258*a9fa9459Szrj // Add a new input section SHNDX, named NAME, with header SHDR, from 3259*a9fa9459Szrj // object OBJECT. RELOC_SHNDX is the index of a relocation section 3260*a9fa9459Szrj // which applies to this section, or 0 if none, or -1 if more than 3261*a9fa9459Szrj // one. HAVE_SECTIONS_SCRIPT is true if we have a SECTIONS clause 3262*a9fa9459Szrj // in a linker script; in that case we need to keep track of input 3263*a9fa9459Szrj // sections associated with an output section. Return the offset 3264*a9fa9459Szrj // within the output section. 3265*a9fa9459Szrj template<int size, bool big_endian> 3266*a9fa9459Szrj off_t 3267*a9fa9459Szrj add_input_section(Layout* layout, Sized_relobj_file<size, big_endian>* object, 3268*a9fa9459Szrj unsigned int shndx, const char* name, 3269*a9fa9459Szrj const elfcpp::Shdr<size, big_endian>& shdr, 3270*a9fa9459Szrj unsigned int reloc_shndx, bool have_sections_script); 3271*a9fa9459Szrj 3272*a9fa9459Szrj // Add generated data POSD to this output section. 3273*a9fa9459Szrj void 3274*a9fa9459Szrj add_output_section_data(Output_section_data* posd); 3275*a9fa9459Szrj 3276*a9fa9459Szrj // Add a relaxed input section PORIS called NAME to this output section 3277*a9fa9459Szrj // with LAYOUT. 3278*a9fa9459Szrj void 3279*a9fa9459Szrj add_relaxed_input_section(Layout* layout, 3280*a9fa9459Szrj Output_relaxed_input_section* poris, 3281*a9fa9459Szrj const std::string& name); 3282*a9fa9459Szrj 3283*a9fa9459Szrj // Return the section name. 3284*a9fa9459Szrj const char* name()3285*a9fa9459Szrj name() const 3286*a9fa9459Szrj { return this->name_; } 3287*a9fa9459Szrj 3288*a9fa9459Szrj // Return the section type. 3289*a9fa9459Szrj elfcpp::Elf_Word type()3290*a9fa9459Szrj type() const 3291*a9fa9459Szrj { return this->type_; } 3292*a9fa9459Szrj 3293*a9fa9459Szrj // Return the section flags. 3294*a9fa9459Szrj elfcpp::Elf_Xword flags()3295*a9fa9459Szrj flags() const 3296*a9fa9459Szrj { return this->flags_; } 3297*a9fa9459Szrj 3298*a9fa9459Szrj typedef std::map<Section_id, unsigned int> Section_layout_order; 3299*a9fa9459Szrj 3300*a9fa9459Szrj void 3301*a9fa9459Szrj update_section_layout(const Section_layout_order* order_map); 3302*a9fa9459Szrj 3303*a9fa9459Szrj // Update the output section flags based on input section flags. 3304*a9fa9459Szrj void 3305*a9fa9459Szrj update_flags_for_input_section(elfcpp::Elf_Xword flags); 3306*a9fa9459Szrj 3307*a9fa9459Szrj // Set the output section flags. 3308*a9fa9459Szrj void set_flags(elfcpp::Elf_Xword flags)3309*a9fa9459Szrj set_flags(elfcpp::Elf_Xword flags) 3310*a9fa9459Szrj { this->flags_ = flags; } 3311*a9fa9459Szrj 3312*a9fa9459Szrj // Return the entsize field. 3313*a9fa9459Szrj uint64_t entsize()3314*a9fa9459Szrj entsize() const 3315*a9fa9459Szrj { return this->entsize_; } 3316*a9fa9459Szrj 3317*a9fa9459Szrj // Set the entsize field. 3318*a9fa9459Szrj void 3319*a9fa9459Szrj set_entsize(uint64_t v); 3320*a9fa9459Szrj 3321*a9fa9459Szrj // Set the load address. 3322*a9fa9459Szrj void set_load_address(uint64_t load_address)3323*a9fa9459Szrj set_load_address(uint64_t load_address) 3324*a9fa9459Szrj { 3325*a9fa9459Szrj this->load_address_ = load_address; 3326*a9fa9459Szrj this->has_load_address_ = true; 3327*a9fa9459Szrj } 3328*a9fa9459Szrj 3329*a9fa9459Szrj // Set the link field to the output section index of a section. 3330*a9fa9459Szrj void set_link_section(const Output_data * od)3331*a9fa9459Szrj set_link_section(const Output_data* od) 3332*a9fa9459Szrj { 3333*a9fa9459Szrj gold_assert(this->link_ == 0 3334*a9fa9459Szrj && !this->should_link_to_symtab_ 3335*a9fa9459Szrj && !this->should_link_to_dynsym_); 3336*a9fa9459Szrj this->link_section_ = od; 3337*a9fa9459Szrj } 3338*a9fa9459Szrj 3339*a9fa9459Szrj // Set the link field to a constant. 3340*a9fa9459Szrj void set_link(unsigned int v)3341*a9fa9459Szrj set_link(unsigned int v) 3342*a9fa9459Szrj { 3343*a9fa9459Szrj gold_assert(this->link_section_ == NULL 3344*a9fa9459Szrj && !this->should_link_to_symtab_ 3345*a9fa9459Szrj && !this->should_link_to_dynsym_); 3346*a9fa9459Szrj this->link_ = v; 3347*a9fa9459Szrj } 3348*a9fa9459Szrj 3349*a9fa9459Szrj // Record that this section should link to the normal symbol table. 3350*a9fa9459Szrj void set_should_link_to_symtab()3351*a9fa9459Szrj set_should_link_to_symtab() 3352*a9fa9459Szrj { 3353*a9fa9459Szrj gold_assert(this->link_section_ == NULL 3354*a9fa9459Szrj && this->link_ == 0 3355*a9fa9459Szrj && !this->should_link_to_dynsym_); 3356*a9fa9459Szrj this->should_link_to_symtab_ = true; 3357*a9fa9459Szrj } 3358*a9fa9459Szrj 3359*a9fa9459Szrj // Record that this section should link to the dynamic symbol table. 3360*a9fa9459Szrj void set_should_link_to_dynsym()3361*a9fa9459Szrj set_should_link_to_dynsym() 3362*a9fa9459Szrj { 3363*a9fa9459Szrj gold_assert(this->link_section_ == NULL 3364*a9fa9459Szrj && this->link_ == 0 3365*a9fa9459Szrj && !this->should_link_to_symtab_); 3366*a9fa9459Szrj this->should_link_to_dynsym_ = true; 3367*a9fa9459Szrj } 3368*a9fa9459Szrj 3369*a9fa9459Szrj // Return the info field. 3370*a9fa9459Szrj unsigned int info()3371*a9fa9459Szrj info() const 3372*a9fa9459Szrj { 3373*a9fa9459Szrj gold_assert(this->info_section_ == NULL 3374*a9fa9459Szrj && this->info_symndx_ == NULL); 3375*a9fa9459Szrj return this->info_; 3376*a9fa9459Szrj } 3377*a9fa9459Szrj 3378*a9fa9459Szrj // Set the info field to the output section index of a section. 3379*a9fa9459Szrj void set_info_section(const Output_section * os)3380*a9fa9459Szrj set_info_section(const Output_section* os) 3381*a9fa9459Szrj { 3382*a9fa9459Szrj gold_assert((this->info_section_ == NULL 3383*a9fa9459Szrj || (this->info_section_ == os 3384*a9fa9459Szrj && this->info_uses_section_index_)) 3385*a9fa9459Szrj && this->info_symndx_ == NULL 3386*a9fa9459Szrj && this->info_ == 0); 3387*a9fa9459Szrj this->info_section_ = os; 3388*a9fa9459Szrj this->info_uses_section_index_= true; 3389*a9fa9459Szrj } 3390*a9fa9459Szrj 3391*a9fa9459Szrj // Set the info field to the symbol table index of a symbol. 3392*a9fa9459Szrj void set_info_symndx(const Symbol * sym)3393*a9fa9459Szrj set_info_symndx(const Symbol* sym) 3394*a9fa9459Szrj { 3395*a9fa9459Szrj gold_assert(this->info_section_ == NULL 3396*a9fa9459Szrj && (this->info_symndx_ == NULL 3397*a9fa9459Szrj || this->info_symndx_ == sym) 3398*a9fa9459Szrj && this->info_ == 0); 3399*a9fa9459Szrj this->info_symndx_ = sym; 3400*a9fa9459Szrj } 3401*a9fa9459Szrj 3402*a9fa9459Szrj // Set the info field to the symbol table index of a section symbol. 3403*a9fa9459Szrj void set_info_section_symndx(const Output_section * os)3404*a9fa9459Szrj set_info_section_symndx(const Output_section* os) 3405*a9fa9459Szrj { 3406*a9fa9459Szrj gold_assert((this->info_section_ == NULL 3407*a9fa9459Szrj || (this->info_section_ == os 3408*a9fa9459Szrj && !this->info_uses_section_index_)) 3409*a9fa9459Szrj && this->info_symndx_ == NULL 3410*a9fa9459Szrj && this->info_ == 0); 3411*a9fa9459Szrj this->info_section_ = os; 3412*a9fa9459Szrj this->info_uses_section_index_ = false; 3413*a9fa9459Szrj } 3414*a9fa9459Szrj 3415*a9fa9459Szrj // Set the info field to a constant. 3416*a9fa9459Szrj void set_info(unsigned int v)3417*a9fa9459Szrj set_info(unsigned int v) 3418*a9fa9459Szrj { 3419*a9fa9459Szrj gold_assert(this->info_section_ == NULL 3420*a9fa9459Szrj && this->info_symndx_ == NULL 3421*a9fa9459Szrj && (this->info_ == 0 3422*a9fa9459Szrj || this->info_ == v)); 3423*a9fa9459Szrj this->info_ = v; 3424*a9fa9459Szrj } 3425*a9fa9459Szrj 3426*a9fa9459Szrj // Set the addralign field. 3427*a9fa9459Szrj void set_addralign(uint64_t v)3428*a9fa9459Szrj set_addralign(uint64_t v) 3429*a9fa9459Szrj { this->addralign_ = v; } 3430*a9fa9459Szrj 3431*a9fa9459Szrj void checkpoint_set_addralign(uint64_t val)3432*a9fa9459Szrj checkpoint_set_addralign(uint64_t val) 3433*a9fa9459Szrj { 3434*a9fa9459Szrj if (this->checkpoint_ != NULL) 3435*a9fa9459Szrj this->checkpoint_->set_addralign(val); 3436*a9fa9459Szrj } 3437*a9fa9459Szrj 3438*a9fa9459Szrj // Whether the output section index has been set. 3439*a9fa9459Szrj bool has_out_shndx()3440*a9fa9459Szrj has_out_shndx() const 3441*a9fa9459Szrj { return this->out_shndx_ != -1U; } 3442*a9fa9459Szrj 3443*a9fa9459Szrj // Indicate that we need a symtab index. 3444*a9fa9459Szrj void set_needs_symtab_index()3445*a9fa9459Szrj set_needs_symtab_index() 3446*a9fa9459Szrj { this->needs_symtab_index_ = true; } 3447*a9fa9459Szrj 3448*a9fa9459Szrj // Return whether we need a symtab index. 3449*a9fa9459Szrj bool needs_symtab_index()3450*a9fa9459Szrj needs_symtab_index() const 3451*a9fa9459Szrj { return this->needs_symtab_index_; } 3452*a9fa9459Szrj 3453*a9fa9459Szrj // Get the symtab index. 3454*a9fa9459Szrj unsigned int symtab_index()3455*a9fa9459Szrj symtab_index() const 3456*a9fa9459Szrj { 3457*a9fa9459Szrj gold_assert(this->symtab_index_ != 0); 3458*a9fa9459Szrj return this->symtab_index_; 3459*a9fa9459Szrj } 3460*a9fa9459Szrj 3461*a9fa9459Szrj // Set the symtab index. 3462*a9fa9459Szrj void set_symtab_index(unsigned int index)3463*a9fa9459Szrj set_symtab_index(unsigned int index) 3464*a9fa9459Szrj { 3465*a9fa9459Szrj gold_assert(index != 0); 3466*a9fa9459Szrj this->symtab_index_ = index; 3467*a9fa9459Szrj } 3468*a9fa9459Szrj 3469*a9fa9459Szrj // Indicate that we need a dynsym index. 3470*a9fa9459Szrj void set_needs_dynsym_index()3471*a9fa9459Szrj set_needs_dynsym_index() 3472*a9fa9459Szrj { this->needs_dynsym_index_ = true; } 3473*a9fa9459Szrj 3474*a9fa9459Szrj // Return whether we need a dynsym index. 3475*a9fa9459Szrj bool needs_dynsym_index()3476*a9fa9459Szrj needs_dynsym_index() const 3477*a9fa9459Szrj { return this->needs_dynsym_index_; } 3478*a9fa9459Szrj 3479*a9fa9459Szrj // Get the dynsym index. 3480*a9fa9459Szrj unsigned int dynsym_index()3481*a9fa9459Szrj dynsym_index() const 3482*a9fa9459Szrj { 3483*a9fa9459Szrj gold_assert(this->dynsym_index_ != 0); 3484*a9fa9459Szrj return this->dynsym_index_; 3485*a9fa9459Szrj } 3486*a9fa9459Szrj 3487*a9fa9459Szrj // Set the dynsym index. 3488*a9fa9459Szrj void set_dynsym_index(unsigned int index)3489*a9fa9459Szrj set_dynsym_index(unsigned int index) 3490*a9fa9459Szrj { 3491*a9fa9459Szrj gold_assert(index != 0); 3492*a9fa9459Szrj this->dynsym_index_ = index; 3493*a9fa9459Szrj } 3494*a9fa9459Szrj 3495*a9fa9459Szrj // Sort the attached input sections. 3496*a9fa9459Szrj void 3497*a9fa9459Szrj sort_attached_input_sections(); 3498*a9fa9459Szrj 3499*a9fa9459Szrj // Return whether the input sections sections attachd to this output 3500*a9fa9459Szrj // section may require sorting. This is used to handle constructor 3501*a9fa9459Szrj // priorities compatibly with GNU ld. 3502*a9fa9459Szrj bool may_sort_attached_input_sections()3503*a9fa9459Szrj may_sort_attached_input_sections() const 3504*a9fa9459Szrj { return this->may_sort_attached_input_sections_; } 3505*a9fa9459Szrj 3506*a9fa9459Szrj // Record that the input sections attached to this output section 3507*a9fa9459Szrj // may require sorting. 3508*a9fa9459Szrj void set_may_sort_attached_input_sections()3509*a9fa9459Szrj set_may_sort_attached_input_sections() 3510*a9fa9459Szrj { this->may_sort_attached_input_sections_ = true; } 3511*a9fa9459Szrj 3512*a9fa9459Szrj // Returns true if input sections must be sorted according to the 3513*a9fa9459Szrj // order in which their name appear in the --section-ordering-file. 3514*a9fa9459Szrj bool input_section_order_specified()3515*a9fa9459Szrj input_section_order_specified() 3516*a9fa9459Szrj { return this->input_section_order_specified_; } 3517*a9fa9459Szrj 3518*a9fa9459Szrj // Record that input sections must be sorted as some of their names 3519*a9fa9459Szrj // match the patterns specified through --section-ordering-file. 3520*a9fa9459Szrj void set_input_section_order_specified()3521*a9fa9459Szrj set_input_section_order_specified() 3522*a9fa9459Szrj { this->input_section_order_specified_ = true; } 3523*a9fa9459Szrj 3524*a9fa9459Szrj // Return whether the input sections attached to this output section 3525*a9fa9459Szrj // require sorting. This is used to handle constructor priorities 3526*a9fa9459Szrj // compatibly with GNU ld. 3527*a9fa9459Szrj bool must_sort_attached_input_sections()3528*a9fa9459Szrj must_sort_attached_input_sections() const 3529*a9fa9459Szrj { return this->must_sort_attached_input_sections_; } 3530*a9fa9459Szrj 3531*a9fa9459Szrj // Record that the input sections attached to this output section 3532*a9fa9459Szrj // require sorting. 3533*a9fa9459Szrj void set_must_sort_attached_input_sections()3534*a9fa9459Szrj set_must_sort_attached_input_sections() 3535*a9fa9459Szrj { this->must_sort_attached_input_sections_ = true; } 3536*a9fa9459Szrj 3537*a9fa9459Szrj // Get the order in which this section appears in the PT_LOAD output 3538*a9fa9459Szrj // segment. 3539*a9fa9459Szrj Output_section_order order()3540*a9fa9459Szrj order() const 3541*a9fa9459Szrj { return this->order_; } 3542*a9fa9459Szrj 3543*a9fa9459Szrj // Set the order for this section. 3544*a9fa9459Szrj void set_order(Output_section_order order)3545*a9fa9459Szrj set_order(Output_section_order order) 3546*a9fa9459Szrj { this->order_ = order; } 3547*a9fa9459Szrj 3548*a9fa9459Szrj // Return whether this section holds relro data--data which has 3549*a9fa9459Szrj // dynamic relocations but which may be marked read-only after the 3550*a9fa9459Szrj // dynamic relocations have been completed. 3551*a9fa9459Szrj bool is_relro()3552*a9fa9459Szrj is_relro() const 3553*a9fa9459Szrj { return this->is_relro_; } 3554*a9fa9459Szrj 3555*a9fa9459Szrj // Record that this section holds relro data. 3556*a9fa9459Szrj void set_is_relro()3557*a9fa9459Szrj set_is_relro() 3558*a9fa9459Szrj { this->is_relro_ = true; } 3559*a9fa9459Szrj 3560*a9fa9459Szrj // Record that this section does not hold relro data. 3561*a9fa9459Szrj void clear_is_relro()3562*a9fa9459Szrj clear_is_relro() 3563*a9fa9459Szrj { this->is_relro_ = false; } 3564*a9fa9459Szrj 3565*a9fa9459Szrj // True if this is a small section: a section which holds small 3566*a9fa9459Szrj // variables. 3567*a9fa9459Szrj bool is_small_section()3568*a9fa9459Szrj is_small_section() const 3569*a9fa9459Szrj { return this->is_small_section_; } 3570*a9fa9459Szrj 3571*a9fa9459Szrj // Record that this is a small section. 3572*a9fa9459Szrj void set_is_small_section()3573*a9fa9459Szrj set_is_small_section() 3574*a9fa9459Szrj { this->is_small_section_ = true; } 3575*a9fa9459Szrj 3576*a9fa9459Szrj // True if this is a large section: a section which holds large 3577*a9fa9459Szrj // variables. 3578*a9fa9459Szrj bool is_large_section()3579*a9fa9459Szrj is_large_section() const 3580*a9fa9459Szrj { return this->is_large_section_; } 3581*a9fa9459Szrj 3582*a9fa9459Szrj // Record that this is a large section. 3583*a9fa9459Szrj void set_is_large_section()3584*a9fa9459Szrj set_is_large_section() 3585*a9fa9459Szrj { this->is_large_section_ = true; } 3586*a9fa9459Szrj 3587*a9fa9459Szrj // True if this is a large data (not BSS) section. 3588*a9fa9459Szrj bool is_large_data_section()3589*a9fa9459Szrj is_large_data_section() 3590*a9fa9459Szrj { return this->is_large_section_ && this->type_ != elfcpp::SHT_NOBITS; } 3591*a9fa9459Szrj 3592*a9fa9459Szrj // Return whether this section should be written after all the input 3593*a9fa9459Szrj // sections are complete. 3594*a9fa9459Szrj bool after_input_sections()3595*a9fa9459Szrj after_input_sections() const 3596*a9fa9459Szrj { return this->after_input_sections_; } 3597*a9fa9459Szrj 3598*a9fa9459Szrj // Record that this section should be written after all the input 3599*a9fa9459Szrj // sections are complete. 3600*a9fa9459Szrj void set_after_input_sections()3601*a9fa9459Szrj set_after_input_sections() 3602*a9fa9459Szrj { this->after_input_sections_ = true; } 3603*a9fa9459Szrj 3604*a9fa9459Szrj // Return whether this section requires postprocessing after all 3605*a9fa9459Szrj // relocations have been applied. 3606*a9fa9459Szrj bool requires_postprocessing()3607*a9fa9459Szrj requires_postprocessing() const 3608*a9fa9459Szrj { return this->requires_postprocessing_; } 3609*a9fa9459Szrj 3610*a9fa9459Szrj bool is_unique_segment()3611*a9fa9459Szrj is_unique_segment() const 3612*a9fa9459Szrj { return this->is_unique_segment_; } 3613*a9fa9459Szrj 3614*a9fa9459Szrj void set_is_unique_segment()3615*a9fa9459Szrj set_is_unique_segment() 3616*a9fa9459Szrj { this->is_unique_segment_ = true; } 3617*a9fa9459Szrj extra_segment_flags()3618*a9fa9459Szrj uint64_t extra_segment_flags() const 3619*a9fa9459Szrj { return this->extra_segment_flags_; } 3620*a9fa9459Szrj 3621*a9fa9459Szrj void set_extra_segment_flags(uint64_t flags)3622*a9fa9459Szrj set_extra_segment_flags(uint64_t flags) 3623*a9fa9459Szrj { this->extra_segment_flags_ = flags; } 3624*a9fa9459Szrj segment_alignment()3625*a9fa9459Szrj uint64_t segment_alignment() const 3626*a9fa9459Szrj { return this->segment_alignment_; } 3627*a9fa9459Szrj 3628*a9fa9459Szrj void set_segment_alignment(uint64_t align)3629*a9fa9459Szrj set_segment_alignment(uint64_t align) 3630*a9fa9459Szrj { this->segment_alignment_ = align; } 3631*a9fa9459Szrj 3632*a9fa9459Szrj // If a section requires postprocessing, return the buffer to use. 3633*a9fa9459Szrj unsigned char* postprocessing_buffer()3634*a9fa9459Szrj postprocessing_buffer() const 3635*a9fa9459Szrj { 3636*a9fa9459Szrj gold_assert(this->postprocessing_buffer_ != NULL); 3637*a9fa9459Szrj return this->postprocessing_buffer_; 3638*a9fa9459Szrj } 3639*a9fa9459Szrj 3640*a9fa9459Szrj // If a section requires postprocessing, create the buffer to use. 3641*a9fa9459Szrj void 3642*a9fa9459Szrj create_postprocessing_buffer(); 3643*a9fa9459Szrj 3644*a9fa9459Szrj // If a section requires postprocessing, this is the size of the 3645*a9fa9459Szrj // buffer to which relocations should be applied. 3646*a9fa9459Szrj off_t postprocessing_buffer_size()3647*a9fa9459Szrj postprocessing_buffer_size() const 3648*a9fa9459Szrj { return this->current_data_size_for_child(); } 3649*a9fa9459Szrj 3650*a9fa9459Szrj // Modify the section name. This is only permitted for an 3651*a9fa9459Szrj // unallocated section, and only before the size has been finalized. 3652*a9fa9459Szrj // Otherwise the name will not get into Layout::namepool_. 3653*a9fa9459Szrj void set_name(const char * newname)3654*a9fa9459Szrj set_name(const char* newname) 3655*a9fa9459Szrj { 3656*a9fa9459Szrj gold_assert((this->flags_ & elfcpp::SHF_ALLOC) == 0); 3657*a9fa9459Szrj gold_assert(!this->is_data_size_valid()); 3658*a9fa9459Szrj this->name_ = newname; 3659*a9fa9459Szrj } 3660*a9fa9459Szrj 3661*a9fa9459Szrj // Return whether the offset OFFSET in the input section SHNDX in 3662*a9fa9459Szrj // object OBJECT is being included in the link. 3663*a9fa9459Szrj bool 3664*a9fa9459Szrj is_input_address_mapped(const Relobj* object, unsigned int shndx, 3665*a9fa9459Szrj off_t offset) const; 3666*a9fa9459Szrj 3667*a9fa9459Szrj // Return the offset within the output section of OFFSET relative to 3668*a9fa9459Szrj // the start of input section SHNDX in object OBJECT. 3669*a9fa9459Szrj section_offset_type 3670*a9fa9459Szrj output_offset(const Relobj* object, unsigned int shndx, 3671*a9fa9459Szrj section_offset_type offset) const; 3672*a9fa9459Szrj 3673*a9fa9459Szrj // Return the output virtual address of OFFSET relative to the start 3674*a9fa9459Szrj // of input section SHNDX in object OBJECT. 3675*a9fa9459Szrj uint64_t 3676*a9fa9459Szrj output_address(const Relobj* object, unsigned int shndx, 3677*a9fa9459Szrj off_t offset) const; 3678*a9fa9459Szrj 3679*a9fa9459Szrj // Look for the merged section for input section SHNDX in object 3680*a9fa9459Szrj // OBJECT. If found, return true, and set *ADDR to the address of 3681*a9fa9459Szrj // the start of the merged section. This is not necessary the 3682*a9fa9459Szrj // output offset corresponding to input offset 0 in the section, 3683*a9fa9459Szrj // since the section may be mapped arbitrarily. 3684*a9fa9459Szrj bool 3685*a9fa9459Szrj find_starting_output_address(const Relobj* object, unsigned int shndx, 3686*a9fa9459Szrj uint64_t* addr) const; 3687*a9fa9459Szrj 3688*a9fa9459Szrj // Record that this output section was found in the SECTIONS clause 3689*a9fa9459Szrj // of a linker script. 3690*a9fa9459Szrj void set_found_in_sections_clause()3691*a9fa9459Szrj set_found_in_sections_clause() 3692*a9fa9459Szrj { this->found_in_sections_clause_ = true; } 3693*a9fa9459Szrj 3694*a9fa9459Szrj // Return whether this output section was found in the SECTIONS 3695*a9fa9459Szrj // clause of a linker script. 3696*a9fa9459Szrj bool found_in_sections_clause()3697*a9fa9459Szrj found_in_sections_clause() const 3698*a9fa9459Szrj { return this->found_in_sections_clause_; } 3699*a9fa9459Szrj 3700*a9fa9459Szrj // Write the section header into *OPHDR. 3701*a9fa9459Szrj template<int size, bool big_endian> 3702*a9fa9459Szrj void 3703*a9fa9459Szrj write_header(const Layout*, const Stringpool*, 3704*a9fa9459Szrj elfcpp::Shdr_write<size, big_endian>*) const; 3705*a9fa9459Szrj 3706*a9fa9459Szrj // The next few calls are for linker script support. 3707*a9fa9459Szrj 3708*a9fa9459Szrj // In some cases we need to keep a list of the input sections 3709*a9fa9459Szrj // associated with this output section. We only need the list if we 3710*a9fa9459Szrj // might have to change the offsets of the input section within the 3711*a9fa9459Szrj // output section after we add the input section. The ordinary 3712*a9fa9459Szrj // input sections will be written out when we process the object 3713*a9fa9459Szrj // file, and as such we don't need to track them here. We do need 3714*a9fa9459Szrj // to track Output_section_data objects here. We store instances of 3715*a9fa9459Szrj // this structure in a std::vector, so it must be a POD. There can 3716*a9fa9459Szrj // be many instances of this structure, so we use a union to save 3717*a9fa9459Szrj // some space. 3718*a9fa9459Szrj class Input_section 3719*a9fa9459Szrj { 3720*a9fa9459Szrj public: Input_section()3721*a9fa9459Szrj Input_section() 3722*a9fa9459Szrj : shndx_(0), p2align_(0) 3723*a9fa9459Szrj { 3724*a9fa9459Szrj this->u1_.data_size = 0; 3725*a9fa9459Szrj this->u2_.object = NULL; 3726*a9fa9459Szrj } 3727*a9fa9459Szrj 3728*a9fa9459Szrj // For an ordinary input section. Input_section(Relobj * object,unsigned int shndx,off_t data_size,uint64_t addralign)3729*a9fa9459Szrj Input_section(Relobj* object, unsigned int shndx, off_t data_size, 3730*a9fa9459Szrj uint64_t addralign) 3731*a9fa9459Szrj : shndx_(shndx), 3732*a9fa9459Szrj p2align_(ffsll(static_cast<long long>(addralign))), 3733*a9fa9459Szrj section_order_index_(0) 3734*a9fa9459Szrj { 3735*a9fa9459Szrj gold_assert(shndx != OUTPUT_SECTION_CODE 3736*a9fa9459Szrj && shndx != MERGE_DATA_SECTION_CODE 3737*a9fa9459Szrj && shndx != MERGE_STRING_SECTION_CODE 3738*a9fa9459Szrj && shndx != RELAXED_INPUT_SECTION_CODE); 3739*a9fa9459Szrj this->u1_.data_size = data_size; 3740*a9fa9459Szrj this->u2_.object = object; 3741*a9fa9459Szrj } 3742*a9fa9459Szrj 3743*a9fa9459Szrj // For a non-merge output section. Input_section(Output_section_data * posd)3744*a9fa9459Szrj Input_section(Output_section_data* posd) 3745*a9fa9459Szrj : shndx_(OUTPUT_SECTION_CODE), p2align_(0), 3746*a9fa9459Szrj section_order_index_(0) 3747*a9fa9459Szrj { 3748*a9fa9459Szrj this->u1_.data_size = 0; 3749*a9fa9459Szrj this->u2_.posd = posd; 3750*a9fa9459Szrj } 3751*a9fa9459Szrj 3752*a9fa9459Szrj // For a merge section. Input_section(Output_section_data * posd,bool is_string,uint64_t entsize)3753*a9fa9459Szrj Input_section(Output_section_data* posd, bool is_string, uint64_t entsize) 3754*a9fa9459Szrj : shndx_(is_string 3755*a9fa9459Szrj ? MERGE_STRING_SECTION_CODE 3756*a9fa9459Szrj : MERGE_DATA_SECTION_CODE), 3757*a9fa9459Szrj p2align_(0), 3758*a9fa9459Szrj section_order_index_(0) 3759*a9fa9459Szrj { 3760*a9fa9459Szrj this->u1_.entsize = entsize; 3761*a9fa9459Szrj this->u2_.posd = posd; 3762*a9fa9459Szrj } 3763*a9fa9459Szrj 3764*a9fa9459Szrj // For a relaxed input section. Input_section(Output_relaxed_input_section * psection)3765*a9fa9459Szrj Input_section(Output_relaxed_input_section* psection) 3766*a9fa9459Szrj : shndx_(RELAXED_INPUT_SECTION_CODE), p2align_(0), 3767*a9fa9459Szrj section_order_index_(0) 3768*a9fa9459Szrj { 3769*a9fa9459Szrj this->u1_.data_size = 0; 3770*a9fa9459Szrj this->u2_.poris = psection; 3771*a9fa9459Szrj } 3772*a9fa9459Szrj 3773*a9fa9459Szrj unsigned int section_order_index()3774*a9fa9459Szrj section_order_index() const 3775*a9fa9459Szrj { 3776*a9fa9459Szrj return this->section_order_index_; 3777*a9fa9459Szrj } 3778*a9fa9459Szrj 3779*a9fa9459Szrj void set_section_order_index(unsigned int number)3780*a9fa9459Szrj set_section_order_index(unsigned int number) 3781*a9fa9459Szrj { 3782*a9fa9459Szrj this->section_order_index_ = number; 3783*a9fa9459Szrj } 3784*a9fa9459Szrj 3785*a9fa9459Szrj // The required alignment. 3786*a9fa9459Szrj uint64_t addralign()3787*a9fa9459Szrj addralign() const 3788*a9fa9459Szrj { 3789*a9fa9459Szrj if (this->p2align_ != 0) 3790*a9fa9459Szrj return static_cast<uint64_t>(1) << (this->p2align_ - 1); 3791*a9fa9459Szrj else if (!this->is_input_section()) 3792*a9fa9459Szrj return this->u2_.posd->addralign(); 3793*a9fa9459Szrj else 3794*a9fa9459Szrj return 0; 3795*a9fa9459Szrj } 3796*a9fa9459Szrj 3797*a9fa9459Szrj // Set the required alignment, which must be either 0 or a power of 2. 3798*a9fa9459Szrj // For input sections that are sub-classes of Output_section_data, a 3799*a9fa9459Szrj // alignment of zero means asking the underlying object for alignment. 3800*a9fa9459Szrj void set_addralign(uint64_t addralign)3801*a9fa9459Szrj set_addralign(uint64_t addralign) 3802*a9fa9459Szrj { 3803*a9fa9459Szrj if (addralign == 0) 3804*a9fa9459Szrj this->p2align_ = 0; 3805*a9fa9459Szrj else 3806*a9fa9459Szrj { 3807*a9fa9459Szrj gold_assert((addralign & (addralign - 1)) == 0); 3808*a9fa9459Szrj this->p2align_ = ffsll(static_cast<long long>(addralign)); 3809*a9fa9459Szrj } 3810*a9fa9459Szrj } 3811*a9fa9459Szrj 3812*a9fa9459Szrj // Return the current required size, without finalization. 3813*a9fa9459Szrj off_t 3814*a9fa9459Szrj current_data_size() const; 3815*a9fa9459Szrj 3816*a9fa9459Szrj // Return the required size. 3817*a9fa9459Szrj off_t 3818*a9fa9459Szrj data_size() const; 3819*a9fa9459Szrj 3820*a9fa9459Szrj // Whether this is an input section. 3821*a9fa9459Szrj bool is_input_section()3822*a9fa9459Szrj is_input_section() const 3823*a9fa9459Szrj { 3824*a9fa9459Szrj return (this->shndx_ != OUTPUT_SECTION_CODE 3825*a9fa9459Szrj && this->shndx_ != MERGE_DATA_SECTION_CODE 3826*a9fa9459Szrj && this->shndx_ != MERGE_STRING_SECTION_CODE 3827*a9fa9459Szrj && this->shndx_ != RELAXED_INPUT_SECTION_CODE); 3828*a9fa9459Szrj } 3829*a9fa9459Szrj 3830*a9fa9459Szrj // Return whether this is a merge section which matches the 3831*a9fa9459Szrj // parameters. 3832*a9fa9459Szrj bool is_merge_section(bool is_string,uint64_t entsize,uint64_t addralign)3833*a9fa9459Szrj is_merge_section(bool is_string, uint64_t entsize, 3834*a9fa9459Szrj uint64_t addralign) const 3835*a9fa9459Szrj { 3836*a9fa9459Szrj return (this->shndx_ == (is_string 3837*a9fa9459Szrj ? MERGE_STRING_SECTION_CODE 3838*a9fa9459Szrj : MERGE_DATA_SECTION_CODE) 3839*a9fa9459Szrj && this->u1_.entsize == entsize 3840*a9fa9459Szrj && this->addralign() == addralign); 3841*a9fa9459Szrj } 3842*a9fa9459Szrj 3843*a9fa9459Szrj // Return whether this is a merge section for some input section. 3844*a9fa9459Szrj bool is_merge_section()3845*a9fa9459Szrj is_merge_section() const 3846*a9fa9459Szrj { 3847*a9fa9459Szrj return (this->shndx_ == MERGE_DATA_SECTION_CODE 3848*a9fa9459Szrj || this->shndx_ == MERGE_STRING_SECTION_CODE); 3849*a9fa9459Szrj } 3850*a9fa9459Szrj 3851*a9fa9459Szrj // Return whether this is a relaxed input section. 3852*a9fa9459Szrj bool is_relaxed_input_section()3853*a9fa9459Szrj is_relaxed_input_section() const 3854*a9fa9459Szrj { return this->shndx_ == RELAXED_INPUT_SECTION_CODE; } 3855*a9fa9459Szrj 3856*a9fa9459Szrj // Return whether this is a generic Output_section_data. 3857*a9fa9459Szrj bool is_output_section_data()3858*a9fa9459Szrj is_output_section_data() const 3859*a9fa9459Szrj { 3860*a9fa9459Szrj return this->shndx_ == OUTPUT_SECTION_CODE; 3861*a9fa9459Szrj } 3862*a9fa9459Szrj 3863*a9fa9459Szrj // Return the object for an input section. 3864*a9fa9459Szrj Relobj* 3865*a9fa9459Szrj relobj() const; 3866*a9fa9459Szrj 3867*a9fa9459Szrj // Return the input section index for an input section. 3868*a9fa9459Szrj unsigned int 3869*a9fa9459Szrj shndx() const; 3870*a9fa9459Szrj 3871*a9fa9459Szrj // For non-input-sections, return the associated Output_section_data 3872*a9fa9459Szrj // object. 3873*a9fa9459Szrj Output_section_data* output_section_data()3874*a9fa9459Szrj output_section_data() const 3875*a9fa9459Szrj { 3876*a9fa9459Szrj gold_assert(!this->is_input_section()); 3877*a9fa9459Szrj return this->u2_.posd; 3878*a9fa9459Szrj } 3879*a9fa9459Szrj 3880*a9fa9459Szrj // For a merge section, return the Output_merge_base pointer. 3881*a9fa9459Szrj Output_merge_base* output_merge_base()3882*a9fa9459Szrj output_merge_base() const 3883*a9fa9459Szrj { 3884*a9fa9459Szrj gold_assert(this->is_merge_section()); 3885*a9fa9459Szrj return this->u2_.pomb; 3886*a9fa9459Szrj } 3887*a9fa9459Szrj 3888*a9fa9459Szrj // Return the Output_relaxed_input_section object. 3889*a9fa9459Szrj Output_relaxed_input_section* relaxed_input_section()3890*a9fa9459Szrj relaxed_input_section() const 3891*a9fa9459Szrj { 3892*a9fa9459Szrj gold_assert(this->is_relaxed_input_section()); 3893*a9fa9459Szrj return this->u2_.poris; 3894*a9fa9459Szrj } 3895*a9fa9459Szrj 3896*a9fa9459Szrj // Set the output section. 3897*a9fa9459Szrj void set_output_section(Output_section * os)3898*a9fa9459Szrj set_output_section(Output_section* os) 3899*a9fa9459Szrj { 3900*a9fa9459Szrj gold_assert(!this->is_input_section()); 3901*a9fa9459Szrj Output_section_data* posd = 3902*a9fa9459Szrj this->is_relaxed_input_section() ? this->u2_.poris : this->u2_.posd; 3903*a9fa9459Szrj posd->set_output_section(os); 3904*a9fa9459Szrj } 3905*a9fa9459Szrj 3906*a9fa9459Szrj // Set the address and file offset. This is called during 3907*a9fa9459Szrj // Layout::finalize. SECTION_FILE_OFFSET is the file offset of 3908*a9fa9459Szrj // the enclosing section. 3909*a9fa9459Szrj void 3910*a9fa9459Szrj set_address_and_file_offset(uint64_t address, off_t file_offset, 3911*a9fa9459Szrj off_t section_file_offset); 3912*a9fa9459Szrj 3913*a9fa9459Szrj // Reset the address and file offset. 3914*a9fa9459Szrj void 3915*a9fa9459Szrj reset_address_and_file_offset(); 3916*a9fa9459Szrj 3917*a9fa9459Szrj // Finalize the data size. 3918*a9fa9459Szrj void 3919*a9fa9459Szrj finalize_data_size(); 3920*a9fa9459Szrj 3921*a9fa9459Szrj // Add an input section, for SHF_MERGE sections. 3922*a9fa9459Szrj bool add_input_section(Relobj * object,unsigned int shndx)3923*a9fa9459Szrj add_input_section(Relobj* object, unsigned int shndx) 3924*a9fa9459Szrj { 3925*a9fa9459Szrj gold_assert(this->shndx_ == MERGE_DATA_SECTION_CODE 3926*a9fa9459Szrj || this->shndx_ == MERGE_STRING_SECTION_CODE); 3927*a9fa9459Szrj return this->u2_.posd->add_input_section(object, shndx); 3928*a9fa9459Szrj } 3929*a9fa9459Szrj 3930*a9fa9459Szrj // Given an input OBJECT, an input section index SHNDX within that 3931*a9fa9459Szrj // object, and an OFFSET relative to the start of that input 3932*a9fa9459Szrj // section, return whether or not the output offset is known. If 3933*a9fa9459Szrj // this function returns true, it sets *POUTPUT to the offset in 3934*a9fa9459Szrj // the output section, relative to the start of the input section 3935*a9fa9459Szrj // in the output section. *POUTPUT may be different from OFFSET 3936*a9fa9459Szrj // for a merged section. 3937*a9fa9459Szrj bool 3938*a9fa9459Szrj output_offset(const Relobj* object, unsigned int shndx, 3939*a9fa9459Szrj section_offset_type offset, 3940*a9fa9459Szrj section_offset_type* poutput) const; 3941*a9fa9459Szrj 3942*a9fa9459Szrj // Write out the data. This does nothing for an input section. 3943*a9fa9459Szrj void 3944*a9fa9459Szrj write(Output_file*); 3945*a9fa9459Szrj 3946*a9fa9459Szrj // Write the data to a buffer. This does nothing for an input 3947*a9fa9459Szrj // section. 3948*a9fa9459Szrj void 3949*a9fa9459Szrj write_to_buffer(unsigned char*); 3950*a9fa9459Szrj 3951*a9fa9459Szrj // Print to a map file. 3952*a9fa9459Szrj void 3953*a9fa9459Szrj print_to_mapfile(Mapfile*) const; 3954*a9fa9459Szrj 3955*a9fa9459Szrj // Print statistics about merge sections to stderr. 3956*a9fa9459Szrj void print_merge_stats(const char * section_name)3957*a9fa9459Szrj print_merge_stats(const char* section_name) 3958*a9fa9459Szrj { 3959*a9fa9459Szrj if (this->shndx_ == MERGE_DATA_SECTION_CODE 3960*a9fa9459Szrj || this->shndx_ == MERGE_STRING_SECTION_CODE) 3961*a9fa9459Szrj this->u2_.posd->print_merge_stats(section_name); 3962*a9fa9459Szrj } 3963*a9fa9459Szrj 3964*a9fa9459Szrj private: 3965*a9fa9459Szrj // Code values which appear in shndx_. If the value is not one of 3966*a9fa9459Szrj // these codes, it is the input section index in the object file. 3967*a9fa9459Szrj enum 3968*a9fa9459Szrj { 3969*a9fa9459Szrj // An Output_section_data. 3970*a9fa9459Szrj OUTPUT_SECTION_CODE = -1U, 3971*a9fa9459Szrj // An Output_section_data for an SHF_MERGE section with 3972*a9fa9459Szrj // SHF_STRINGS not set. 3973*a9fa9459Szrj MERGE_DATA_SECTION_CODE = -2U, 3974*a9fa9459Szrj // An Output_section_data for an SHF_MERGE section with 3975*a9fa9459Szrj // SHF_STRINGS set. 3976*a9fa9459Szrj MERGE_STRING_SECTION_CODE = -3U, 3977*a9fa9459Szrj // An Output_section_data for a relaxed input section. 3978*a9fa9459Szrj RELAXED_INPUT_SECTION_CODE = -4U 3979*a9fa9459Szrj }; 3980*a9fa9459Szrj 3981*a9fa9459Szrj // For an ordinary input section, this is the section index in the 3982*a9fa9459Szrj // input file. For an Output_section_data, this is 3983*a9fa9459Szrj // OUTPUT_SECTION_CODE or MERGE_DATA_SECTION_CODE or 3984*a9fa9459Szrj // MERGE_STRING_SECTION_CODE. 3985*a9fa9459Szrj unsigned int shndx_; 3986*a9fa9459Szrj // The required alignment, stored as a power of 2. 3987*a9fa9459Szrj unsigned int p2align_; 3988*a9fa9459Szrj union 3989*a9fa9459Szrj { 3990*a9fa9459Szrj // For an ordinary input section, the section size. 3991*a9fa9459Szrj off_t data_size; 3992*a9fa9459Szrj // For OUTPUT_SECTION_CODE or RELAXED_INPUT_SECTION_CODE, this is not 3993*a9fa9459Szrj // used. For MERGE_DATA_SECTION_CODE or MERGE_STRING_SECTION_CODE, the 3994*a9fa9459Szrj // entity size. 3995*a9fa9459Szrj uint64_t entsize; 3996*a9fa9459Szrj } u1_; 3997*a9fa9459Szrj union 3998*a9fa9459Szrj { 3999*a9fa9459Szrj // For an ordinary input section, the object which holds the 4000*a9fa9459Szrj // input section. 4001*a9fa9459Szrj Relobj* object; 4002*a9fa9459Szrj // For OUTPUT_SECTION_CODE or MERGE_DATA_SECTION_CODE or 4003*a9fa9459Szrj // MERGE_STRING_SECTION_CODE, the data. 4004*a9fa9459Szrj Output_section_data* posd; 4005*a9fa9459Szrj Output_merge_base* pomb; 4006*a9fa9459Szrj // For RELAXED_INPUT_SECTION_CODE, the data. 4007*a9fa9459Szrj Output_relaxed_input_section* poris; 4008*a9fa9459Szrj } u2_; 4009*a9fa9459Szrj // The line number of the pattern it matches in the --section-ordering-file 4010*a9fa9459Szrj // file. It is 0 if does not match any pattern. 4011*a9fa9459Szrj unsigned int section_order_index_; 4012*a9fa9459Szrj }; 4013*a9fa9459Szrj 4014*a9fa9459Szrj // Store the list of input sections for this Output_section into the 4015*a9fa9459Szrj // list passed in. This removes the input sections, leaving only 4016*a9fa9459Szrj // any Output_section_data elements. This returns the size of those 4017*a9fa9459Szrj // Output_section_data elements. ADDRESS is the address of this 4018*a9fa9459Szrj // output section. FILL is the fill value to use, in case there are 4019*a9fa9459Szrj // any spaces between the remaining Output_section_data elements. 4020*a9fa9459Szrj uint64_t 4021*a9fa9459Szrj get_input_sections(uint64_t address, const std::string& fill, 4022*a9fa9459Szrj std::list<Input_section>*); 4023*a9fa9459Szrj 4024*a9fa9459Szrj // Add a script input section. A script input section can either be 4025*a9fa9459Szrj // a plain input section or a sub-class of Output_section_data. 4026*a9fa9459Szrj void 4027*a9fa9459Szrj add_script_input_section(const Input_section& input_section); 4028*a9fa9459Szrj 4029*a9fa9459Szrj // Set the current size of the output section. 4030*a9fa9459Szrj void set_current_data_size(off_t size)4031*a9fa9459Szrj set_current_data_size(off_t size) 4032*a9fa9459Szrj { this->set_current_data_size_for_child(size); } 4033*a9fa9459Szrj 4034*a9fa9459Szrj // End of linker script support. 4035*a9fa9459Szrj 4036*a9fa9459Szrj // Save states before doing section layout. 4037*a9fa9459Szrj // This is used for relaxation. 4038*a9fa9459Szrj void 4039*a9fa9459Szrj save_states(); 4040*a9fa9459Szrj 4041*a9fa9459Szrj // Restore states prior to section layout. 4042*a9fa9459Szrj void 4043*a9fa9459Szrj restore_states(); 4044*a9fa9459Szrj 4045*a9fa9459Szrj // Discard states. 4046*a9fa9459Szrj void 4047*a9fa9459Szrj discard_states(); 4048*a9fa9459Szrj 4049*a9fa9459Szrj // Convert existing input sections to relaxed input sections. 4050*a9fa9459Szrj void 4051*a9fa9459Szrj convert_input_sections_to_relaxed_sections( 4052*a9fa9459Szrj const std::vector<Output_relaxed_input_section*>& sections); 4053*a9fa9459Szrj 4054*a9fa9459Szrj // Find a relaxed input section to an input section in OBJECT 4055*a9fa9459Szrj // with index SHNDX. Return NULL if none is found. 4056*a9fa9459Szrj const Output_relaxed_input_section* 4057*a9fa9459Szrj find_relaxed_input_section(const Relobj* object, unsigned int shndx) const; 4058*a9fa9459Szrj 4059*a9fa9459Szrj // Whether section offsets need adjustment due to relaxation. 4060*a9fa9459Szrj bool section_offsets_need_adjustment()4061*a9fa9459Szrj section_offsets_need_adjustment() const 4062*a9fa9459Szrj { return this->section_offsets_need_adjustment_; } 4063*a9fa9459Szrj 4064*a9fa9459Szrj // Set section_offsets_need_adjustment to be true. 4065*a9fa9459Szrj void set_section_offsets_need_adjustment()4066*a9fa9459Szrj set_section_offsets_need_adjustment() 4067*a9fa9459Szrj { this->section_offsets_need_adjustment_ = true; } 4068*a9fa9459Szrj 4069*a9fa9459Szrj // Set section_offsets_need_adjustment to be false. 4070*a9fa9459Szrj void clear_section_offsets_need_adjustment()4071*a9fa9459Szrj clear_section_offsets_need_adjustment() 4072*a9fa9459Szrj { this->section_offsets_need_adjustment_ = false; } 4073*a9fa9459Szrj 4074*a9fa9459Szrj // Adjust section offsets of input sections in this. This is 4075*a9fa9459Szrj // requires if relaxation caused some input sections to change sizes. 4076*a9fa9459Szrj void 4077*a9fa9459Szrj adjust_section_offsets(); 4078*a9fa9459Szrj 4079*a9fa9459Szrj // Whether this is a NOLOAD section. 4080*a9fa9459Szrj bool is_noload()4081*a9fa9459Szrj is_noload() const 4082*a9fa9459Szrj { return this->is_noload_; } 4083*a9fa9459Szrj 4084*a9fa9459Szrj // Set NOLOAD flag. 4085*a9fa9459Szrj void set_is_noload()4086*a9fa9459Szrj set_is_noload() 4087*a9fa9459Szrj { this->is_noload_ = true; } 4088*a9fa9459Szrj 4089*a9fa9459Szrj // Print merge statistics to stderr. 4090*a9fa9459Szrj void 4091*a9fa9459Szrj print_merge_stats(); 4092*a9fa9459Szrj 4093*a9fa9459Szrj // Set a fixed layout for the section. Used for incremental update links. 4094*a9fa9459Szrj void 4095*a9fa9459Szrj set_fixed_layout(uint64_t sh_addr, off_t sh_offset, off_t sh_size, 4096*a9fa9459Szrj uint64_t sh_addralign); 4097*a9fa9459Szrj 4098*a9fa9459Szrj // Return TRUE if the section has a fixed layout. 4099*a9fa9459Szrj bool has_fixed_layout()4100*a9fa9459Szrj has_fixed_layout() const 4101*a9fa9459Szrj { return this->has_fixed_layout_; } 4102*a9fa9459Szrj 4103*a9fa9459Szrj // Set flag to allow patch space for this section. Used for full 4104*a9fa9459Szrj // incremental links. 4105*a9fa9459Szrj void set_is_patch_space_allowed()4106*a9fa9459Szrj set_is_patch_space_allowed() 4107*a9fa9459Szrj { this->is_patch_space_allowed_ = true; } 4108*a9fa9459Szrj 4109*a9fa9459Szrj // Set a fill method to use for free space left in the output section 4110*a9fa9459Szrj // during incremental links. 4111*a9fa9459Szrj void set_free_space_fill(Output_fill * free_space_fill)4112*a9fa9459Szrj set_free_space_fill(Output_fill* free_space_fill) 4113*a9fa9459Szrj { 4114*a9fa9459Szrj this->free_space_fill_ = free_space_fill; 4115*a9fa9459Szrj this->free_list_.set_min_hole_size(free_space_fill->minimum_hole_size()); 4116*a9fa9459Szrj } 4117*a9fa9459Szrj 4118*a9fa9459Szrj // Reserve space within the fixed layout for the section. Used for 4119*a9fa9459Szrj // incremental update links. 4120*a9fa9459Szrj void 4121*a9fa9459Szrj reserve(uint64_t sh_offset, uint64_t sh_size); 4122*a9fa9459Szrj 4123*a9fa9459Szrj // Allocate space from the free list for the section. Used for 4124*a9fa9459Szrj // incremental update links. 4125*a9fa9459Szrj off_t 4126*a9fa9459Szrj allocate(off_t len, uint64_t addralign); 4127*a9fa9459Szrj 4128*a9fa9459Szrj typedef std::vector<Input_section> Input_section_list; 4129*a9fa9459Szrj 4130*a9fa9459Szrj // Allow access to the input sections. 4131*a9fa9459Szrj const Input_section_list& input_sections()4132*a9fa9459Szrj input_sections() const 4133*a9fa9459Szrj { return this->input_sections_; } 4134*a9fa9459Szrj 4135*a9fa9459Szrj Input_section_list& input_sections()4136*a9fa9459Szrj input_sections() 4137*a9fa9459Szrj { return this->input_sections_; } 4138*a9fa9459Szrj 4139*a9fa9459Szrj protected: 4140*a9fa9459Szrj // Return the output section--i.e., the object itself. 4141*a9fa9459Szrj Output_section* do_output_section()4142*a9fa9459Szrj do_output_section() 4143*a9fa9459Szrj { return this; } 4144*a9fa9459Szrj 4145*a9fa9459Szrj const Output_section* do_output_section()4146*a9fa9459Szrj do_output_section() const 4147*a9fa9459Szrj { return this; } 4148*a9fa9459Szrj 4149*a9fa9459Szrj // Return the section index in the output file. 4150*a9fa9459Szrj unsigned int do_out_shndx()4151*a9fa9459Szrj do_out_shndx() const 4152*a9fa9459Szrj { 4153*a9fa9459Szrj gold_assert(this->out_shndx_ != -1U); 4154*a9fa9459Szrj return this->out_shndx_; 4155*a9fa9459Szrj } 4156*a9fa9459Szrj 4157*a9fa9459Szrj // Set the output section index. 4158*a9fa9459Szrj void do_set_out_shndx(unsigned int shndx)4159*a9fa9459Szrj do_set_out_shndx(unsigned int shndx) 4160*a9fa9459Szrj { 4161*a9fa9459Szrj gold_assert(this->out_shndx_ == -1U || this->out_shndx_ == shndx); 4162*a9fa9459Szrj this->out_shndx_ = shndx; 4163*a9fa9459Szrj } 4164*a9fa9459Szrj 4165*a9fa9459Szrj // Update the data size of the Output_section. For a typical 4166*a9fa9459Szrj // Output_section, there is nothing to do, but if there are any 4167*a9fa9459Szrj // Output_section_data objects we need to do a trial layout 4168*a9fa9459Szrj // here. 4169*a9fa9459Szrj virtual void 4170*a9fa9459Szrj update_data_size(); 4171*a9fa9459Szrj 4172*a9fa9459Szrj // Set the final data size of the Output_section. For a typical 4173*a9fa9459Szrj // Output_section, there is nothing to do, but if there are any 4174*a9fa9459Szrj // Output_section_data objects we need to set their final addresses 4175*a9fa9459Szrj // here. 4176*a9fa9459Szrj virtual void 4177*a9fa9459Szrj set_final_data_size(); 4178*a9fa9459Szrj 4179*a9fa9459Szrj // Reset the address and file offset. 4180*a9fa9459Szrj void 4181*a9fa9459Szrj do_reset_address_and_file_offset(); 4182*a9fa9459Szrj 4183*a9fa9459Szrj // Return true if address and file offset already have reset values. In 4184*a9fa9459Szrj // other words, calling reset_address_and_file_offset will not change them. 4185*a9fa9459Szrj bool 4186*a9fa9459Szrj do_address_and_file_offset_have_reset_values() const; 4187*a9fa9459Szrj 4188*a9fa9459Szrj // Write the data to the file. For a typical Output_section, this 4189*a9fa9459Szrj // does nothing: the data is written out by calling Object::Relocate 4190*a9fa9459Szrj // on each input object. But if there are any Output_section_data 4191*a9fa9459Szrj // objects we do need to write them out here. 4192*a9fa9459Szrj virtual void 4193*a9fa9459Szrj do_write(Output_file*); 4194*a9fa9459Szrj 4195*a9fa9459Szrj // Return the address alignment--function required by parent class. 4196*a9fa9459Szrj uint64_t do_addralign()4197*a9fa9459Szrj do_addralign() const 4198*a9fa9459Szrj { return this->addralign_; } 4199*a9fa9459Szrj 4200*a9fa9459Szrj // Return whether there is a load address. 4201*a9fa9459Szrj bool do_has_load_address()4202*a9fa9459Szrj do_has_load_address() const 4203*a9fa9459Szrj { return this->has_load_address_; } 4204*a9fa9459Szrj 4205*a9fa9459Szrj // Return the load address. 4206*a9fa9459Szrj uint64_t do_load_address()4207*a9fa9459Szrj do_load_address() const 4208*a9fa9459Szrj { 4209*a9fa9459Szrj gold_assert(this->has_load_address_); 4210*a9fa9459Szrj return this->load_address_; 4211*a9fa9459Szrj } 4212*a9fa9459Szrj 4213*a9fa9459Szrj // Return whether this is an Output_section. 4214*a9fa9459Szrj bool do_is_section()4215*a9fa9459Szrj do_is_section() const 4216*a9fa9459Szrj { return true; } 4217*a9fa9459Szrj 4218*a9fa9459Szrj // Return whether this is a section of the specified type. 4219*a9fa9459Szrj bool do_is_section_type(elfcpp::Elf_Word type)4220*a9fa9459Szrj do_is_section_type(elfcpp::Elf_Word type) const 4221*a9fa9459Szrj { return this->type_ == type; } 4222*a9fa9459Szrj 4223*a9fa9459Szrj // Return whether the specified section flag is set. 4224*a9fa9459Szrj bool do_is_section_flag_set(elfcpp::Elf_Xword flag)4225*a9fa9459Szrj do_is_section_flag_set(elfcpp::Elf_Xword flag) const 4226*a9fa9459Szrj { return (this->flags_ & flag) != 0; } 4227*a9fa9459Szrj 4228*a9fa9459Szrj // Set the TLS offset. Called only for SHT_TLS sections. 4229*a9fa9459Szrj void 4230*a9fa9459Szrj do_set_tls_offset(uint64_t tls_base); 4231*a9fa9459Szrj 4232*a9fa9459Szrj // Return the TLS offset, relative to the base of the TLS segment. 4233*a9fa9459Szrj // Valid only for SHT_TLS sections. 4234*a9fa9459Szrj uint64_t do_tls_offset()4235*a9fa9459Szrj do_tls_offset() const 4236*a9fa9459Szrj { return this->tls_offset_; } 4237*a9fa9459Szrj 4238*a9fa9459Szrj // This may be implemented by a child class. 4239*a9fa9459Szrj virtual void do_finalize_name(Layout *)4240*a9fa9459Szrj do_finalize_name(Layout*) 4241*a9fa9459Szrj { } 4242*a9fa9459Szrj 4243*a9fa9459Szrj // Print to the map file. 4244*a9fa9459Szrj virtual void 4245*a9fa9459Szrj do_print_to_mapfile(Mapfile*) const; 4246*a9fa9459Szrj 4247*a9fa9459Szrj // Record that this section requires postprocessing after all 4248*a9fa9459Szrj // relocations have been applied. This is called by a child class. 4249*a9fa9459Szrj void set_requires_postprocessing()4250*a9fa9459Szrj set_requires_postprocessing() 4251*a9fa9459Szrj { 4252*a9fa9459Szrj this->requires_postprocessing_ = true; 4253*a9fa9459Szrj this->after_input_sections_ = true; 4254*a9fa9459Szrj } 4255*a9fa9459Szrj 4256*a9fa9459Szrj // Write all the data of an Output_section into the postprocessing 4257*a9fa9459Szrj // buffer. 4258*a9fa9459Szrj void 4259*a9fa9459Szrj write_to_postprocessing_buffer(); 4260*a9fa9459Szrj 4261*a9fa9459Szrj // Whether this always keeps an input section list 4262*a9fa9459Szrj bool always_keeps_input_sections()4263*a9fa9459Szrj always_keeps_input_sections() const 4264*a9fa9459Szrj { return this->always_keeps_input_sections_; } 4265*a9fa9459Szrj 4266*a9fa9459Szrj // Always keep an input section list. 4267*a9fa9459Szrj void set_always_keeps_input_sections()4268*a9fa9459Szrj set_always_keeps_input_sections() 4269*a9fa9459Szrj { 4270*a9fa9459Szrj gold_assert(this->current_data_size_for_child() == 0); 4271*a9fa9459Szrj this->always_keeps_input_sections_ = true; 4272*a9fa9459Szrj } 4273*a9fa9459Szrj 4274*a9fa9459Szrj private: 4275*a9fa9459Szrj // We only save enough information to undo the effects of section layout. 4276*a9fa9459Szrj class Checkpoint_output_section 4277*a9fa9459Szrj { 4278*a9fa9459Szrj public: Checkpoint_output_section(uint64_t addralign,elfcpp::Elf_Xword flags,const Input_section_list & input_sections,off_t first_input_offset,bool attached_input_sections_are_sorted)4279*a9fa9459Szrj Checkpoint_output_section(uint64_t addralign, elfcpp::Elf_Xword flags, 4280*a9fa9459Szrj const Input_section_list& input_sections, 4281*a9fa9459Szrj off_t first_input_offset, 4282*a9fa9459Szrj bool attached_input_sections_are_sorted) 4283*a9fa9459Szrj : addralign_(addralign), flags_(flags), 4284*a9fa9459Szrj input_sections_(input_sections), 4285*a9fa9459Szrj input_sections_size_(input_sections_.size()), 4286*a9fa9459Szrj input_sections_copy_(), first_input_offset_(first_input_offset), 4287*a9fa9459Szrj attached_input_sections_are_sorted_(attached_input_sections_are_sorted) 4288*a9fa9459Szrj { } 4289*a9fa9459Szrj 4290*a9fa9459Szrj virtual ~Checkpoint_output_section()4291*a9fa9459Szrj ~Checkpoint_output_section() 4292*a9fa9459Szrj { } 4293*a9fa9459Szrj 4294*a9fa9459Szrj // Return the address alignment. 4295*a9fa9459Szrj uint64_t addralign()4296*a9fa9459Szrj addralign() const 4297*a9fa9459Szrj { return this->addralign_; } 4298*a9fa9459Szrj 4299*a9fa9459Szrj void set_addralign(uint64_t val)4300*a9fa9459Szrj set_addralign(uint64_t val) 4301*a9fa9459Szrj { this->addralign_ = val; } 4302*a9fa9459Szrj 4303*a9fa9459Szrj // Return the section flags. 4304*a9fa9459Szrj elfcpp::Elf_Xword flags()4305*a9fa9459Szrj flags() const 4306*a9fa9459Szrj { return this->flags_; } 4307*a9fa9459Szrj 4308*a9fa9459Szrj // Return a reference to the input section list copy. 4309*a9fa9459Szrj Input_section_list* input_sections()4310*a9fa9459Szrj input_sections() 4311*a9fa9459Szrj { return &this->input_sections_copy_; } 4312*a9fa9459Szrj 4313*a9fa9459Szrj // Return the size of input_sections at the time when checkpoint is 4314*a9fa9459Szrj // taken. 4315*a9fa9459Szrj size_t input_sections_size()4316*a9fa9459Szrj input_sections_size() const 4317*a9fa9459Szrj { return this->input_sections_size_; } 4318*a9fa9459Szrj 4319*a9fa9459Szrj // Whether input sections are copied. 4320*a9fa9459Szrj bool input_sections_saved()4321*a9fa9459Szrj input_sections_saved() const 4322*a9fa9459Szrj { return this->input_sections_copy_.size() == this->input_sections_size_; } 4323*a9fa9459Szrj 4324*a9fa9459Szrj off_t first_input_offset()4325*a9fa9459Szrj first_input_offset() const 4326*a9fa9459Szrj { return this->first_input_offset_; } 4327*a9fa9459Szrj 4328*a9fa9459Szrj bool attached_input_sections_are_sorted()4329*a9fa9459Szrj attached_input_sections_are_sorted() const 4330*a9fa9459Szrj { return this->attached_input_sections_are_sorted_; } 4331*a9fa9459Szrj 4332*a9fa9459Szrj // Save input sections. 4333*a9fa9459Szrj void save_input_sections()4334*a9fa9459Szrj save_input_sections() 4335*a9fa9459Szrj { 4336*a9fa9459Szrj this->input_sections_copy_.reserve(this->input_sections_size_); 4337*a9fa9459Szrj this->input_sections_copy_.clear(); 4338*a9fa9459Szrj Input_section_list::const_iterator p = this->input_sections_.begin(); 4339*a9fa9459Szrj gold_assert(this->input_sections_size_ >= this->input_sections_.size()); 4340*a9fa9459Szrj for(size_t i = 0; i < this->input_sections_size_ ; i++, ++p) 4341*a9fa9459Szrj this->input_sections_copy_.push_back(*p); 4342*a9fa9459Szrj } 4343*a9fa9459Szrj 4344*a9fa9459Szrj private: 4345*a9fa9459Szrj // The section alignment. 4346*a9fa9459Szrj uint64_t addralign_; 4347*a9fa9459Szrj // The section flags. 4348*a9fa9459Szrj elfcpp::Elf_Xword flags_; 4349*a9fa9459Szrj // Reference to the input sections to be checkpointed. 4350*a9fa9459Szrj const Input_section_list& input_sections_; 4351*a9fa9459Szrj // Size of the checkpointed portion of input_sections_; 4352*a9fa9459Szrj size_t input_sections_size_; 4353*a9fa9459Szrj // Copy of input sections. 4354*a9fa9459Szrj Input_section_list input_sections_copy_; 4355*a9fa9459Szrj // The offset of the first entry in input_sections_. 4356*a9fa9459Szrj off_t first_input_offset_; 4357*a9fa9459Szrj // True if the input sections attached to this output section have 4358*a9fa9459Szrj // already been sorted. 4359*a9fa9459Szrj bool attached_input_sections_are_sorted_; 4360*a9fa9459Szrj }; 4361*a9fa9459Szrj 4362*a9fa9459Szrj // This class is used to sort the input sections. 4363*a9fa9459Szrj class Input_section_sort_entry; 4364*a9fa9459Szrj 4365*a9fa9459Szrj // This is the sort comparison function for ctors and dtors. 4366*a9fa9459Szrj struct Input_section_sort_compare 4367*a9fa9459Szrj { 4368*a9fa9459Szrj bool 4369*a9fa9459Szrj operator()(const Input_section_sort_entry&, 4370*a9fa9459Szrj const Input_section_sort_entry&) const; 4371*a9fa9459Szrj }; 4372*a9fa9459Szrj 4373*a9fa9459Szrj // This is the sort comparison function for .init_array and .fini_array. 4374*a9fa9459Szrj struct Input_section_sort_init_fini_compare 4375*a9fa9459Szrj { 4376*a9fa9459Szrj bool 4377*a9fa9459Szrj operator()(const Input_section_sort_entry&, 4378*a9fa9459Szrj const Input_section_sort_entry&) const; 4379*a9fa9459Szrj }; 4380*a9fa9459Szrj 4381*a9fa9459Szrj // This is the sort comparison function when a section order is specified 4382*a9fa9459Szrj // from an input file. 4383*a9fa9459Szrj struct Input_section_sort_section_order_index_compare 4384*a9fa9459Szrj { 4385*a9fa9459Szrj bool 4386*a9fa9459Szrj operator()(const Input_section_sort_entry&, 4387*a9fa9459Szrj const Input_section_sort_entry&) const; 4388*a9fa9459Szrj }; 4389*a9fa9459Szrj 4390*a9fa9459Szrj // This is the sort comparison function for .text to sort sections with 4391*a9fa9459Szrj // prefixes .text.{unlikely,exit,startup,hot} before other sections. 4392*a9fa9459Szrj struct Input_section_sort_section_prefix_special_ordering_compare 4393*a9fa9459Szrj { 4394*a9fa9459Szrj bool 4395*a9fa9459Szrj operator()(const Input_section_sort_entry&, 4396*a9fa9459Szrj const Input_section_sort_entry&) const; 4397*a9fa9459Szrj }; 4398*a9fa9459Szrj 4399*a9fa9459Szrj // This is the sort comparison function for sorting sections by name. 4400*a9fa9459Szrj struct Input_section_sort_section_name_compare 4401*a9fa9459Szrj { 4402*a9fa9459Szrj bool 4403*a9fa9459Szrj operator()(const Input_section_sort_entry&, 4404*a9fa9459Szrj const Input_section_sort_entry&) const; 4405*a9fa9459Szrj }; 4406*a9fa9459Szrj 4407*a9fa9459Szrj // Fill data. This is used to fill in data between input sections. 4408*a9fa9459Szrj // It is also used for data statements (BYTE, WORD, etc.) in linker 4409*a9fa9459Szrj // scripts. When we have to keep track of the input sections, we 4410*a9fa9459Szrj // can use an Output_data_const, but we don't want to have to keep 4411*a9fa9459Szrj // track of input sections just to implement fills. 4412*a9fa9459Szrj class Fill 4413*a9fa9459Szrj { 4414*a9fa9459Szrj public: Fill(off_t section_offset,off_t length)4415*a9fa9459Szrj Fill(off_t section_offset, off_t length) 4416*a9fa9459Szrj : section_offset_(section_offset), 4417*a9fa9459Szrj length_(convert_to_section_size_type(length)) 4418*a9fa9459Szrj { } 4419*a9fa9459Szrj 4420*a9fa9459Szrj // Return section offset. 4421*a9fa9459Szrj off_t section_offset()4422*a9fa9459Szrj section_offset() const 4423*a9fa9459Szrj { return this->section_offset_; } 4424*a9fa9459Szrj 4425*a9fa9459Szrj // Return fill length. 4426*a9fa9459Szrj section_size_type length()4427*a9fa9459Szrj length() const 4428*a9fa9459Szrj { return this->length_; } 4429*a9fa9459Szrj 4430*a9fa9459Szrj private: 4431*a9fa9459Szrj // The offset within the output section. 4432*a9fa9459Szrj off_t section_offset_; 4433*a9fa9459Szrj // The length of the space to fill. 4434*a9fa9459Szrj section_size_type length_; 4435*a9fa9459Szrj }; 4436*a9fa9459Szrj 4437*a9fa9459Szrj typedef std::vector<Fill> Fill_list; 4438*a9fa9459Szrj 4439*a9fa9459Szrj // Map used during relaxation of existing sections. This map 4440*a9fa9459Szrj // a section id an input section list index. We assume that 4441*a9fa9459Szrj // Input_section_list is a vector. 4442*a9fa9459Szrj typedef Unordered_map<Section_id, size_t, Section_id_hash> Relaxation_map; 4443*a9fa9459Szrj 4444*a9fa9459Szrj // Add a new output section by Input_section. 4445*a9fa9459Szrj void 4446*a9fa9459Szrj add_output_section_data(Input_section*); 4447*a9fa9459Szrj 4448*a9fa9459Szrj // Add an SHF_MERGE input section. Returns true if the section was 4449*a9fa9459Szrj // handled. If KEEPS_INPUT_SECTIONS is true, the output merge section 4450*a9fa9459Szrj // stores information about the merged input sections. 4451*a9fa9459Szrj bool 4452*a9fa9459Szrj add_merge_input_section(Relobj* object, unsigned int shndx, uint64_t flags, 4453*a9fa9459Szrj uint64_t entsize, uint64_t addralign, 4454*a9fa9459Szrj bool keeps_input_sections); 4455*a9fa9459Szrj 4456*a9fa9459Szrj // Add an output SHF_MERGE section POSD to this output section. 4457*a9fa9459Szrj // IS_STRING indicates whether it is a SHF_STRINGS section, and 4458*a9fa9459Szrj // ENTSIZE is the entity size. This returns the entry added to 4459*a9fa9459Szrj // input_sections_. 4460*a9fa9459Szrj void 4461*a9fa9459Szrj add_output_merge_section(Output_section_data* posd, bool is_string, 4462*a9fa9459Szrj uint64_t entsize); 4463*a9fa9459Szrj 4464*a9fa9459Szrj // Find the merge section into which an input section with index SHNDX in 4465*a9fa9459Szrj // OBJECT has been added. Return NULL if none found. 4466*a9fa9459Szrj const Output_section_data* 4467*a9fa9459Szrj find_merge_section(const Relobj* object, unsigned int shndx) const; 4468*a9fa9459Szrj 4469*a9fa9459Szrj // Build a relaxation map. 4470*a9fa9459Szrj void 4471*a9fa9459Szrj build_relaxation_map( 4472*a9fa9459Szrj const Input_section_list& input_sections, 4473*a9fa9459Szrj size_t limit, 4474*a9fa9459Szrj Relaxation_map* map) const; 4475*a9fa9459Szrj 4476*a9fa9459Szrj // Convert input sections in an input section list into relaxed sections. 4477*a9fa9459Szrj void 4478*a9fa9459Szrj convert_input_sections_in_list_to_relaxed_sections( 4479*a9fa9459Szrj const std::vector<Output_relaxed_input_section*>& relaxed_sections, 4480*a9fa9459Szrj const Relaxation_map& map, 4481*a9fa9459Szrj Input_section_list* input_sections); 4482*a9fa9459Szrj 4483*a9fa9459Szrj // Build the lookup maps for merge and relaxed input sections. 4484*a9fa9459Szrj void 4485*a9fa9459Szrj build_lookup_maps() const; 4486*a9fa9459Szrj 4487*a9fa9459Szrj // Most of these fields are only valid after layout. 4488*a9fa9459Szrj 4489*a9fa9459Szrj // The name of the section. This will point into a Stringpool. 4490*a9fa9459Szrj const char* name_; 4491*a9fa9459Szrj // The section address is in the parent class. 4492*a9fa9459Szrj // The section alignment. 4493*a9fa9459Szrj uint64_t addralign_; 4494*a9fa9459Szrj // The section entry size. 4495*a9fa9459Szrj uint64_t entsize_; 4496*a9fa9459Szrj // The load address. This is only used when using a linker script 4497*a9fa9459Szrj // with a SECTIONS clause. The has_load_address_ field indicates 4498*a9fa9459Szrj // whether this field is valid. 4499*a9fa9459Szrj uint64_t load_address_; 4500*a9fa9459Szrj // The file offset is in the parent class. 4501*a9fa9459Szrj // Set the section link field to the index of this section. 4502*a9fa9459Szrj const Output_data* link_section_; 4503*a9fa9459Szrj // If link_section_ is NULL, this is the link field. 4504*a9fa9459Szrj unsigned int link_; 4505*a9fa9459Szrj // Set the section info field to the index of this section. 4506*a9fa9459Szrj const Output_section* info_section_; 4507*a9fa9459Szrj // If info_section_ is NULL, set the info field to the symbol table 4508*a9fa9459Szrj // index of this symbol. 4509*a9fa9459Szrj const Symbol* info_symndx_; 4510*a9fa9459Szrj // If info_section_ and info_symndx_ are NULL, this is the section 4511*a9fa9459Szrj // info field. 4512*a9fa9459Szrj unsigned int info_; 4513*a9fa9459Szrj // The section type. 4514*a9fa9459Szrj const elfcpp::Elf_Word type_; 4515*a9fa9459Szrj // The section flags. 4516*a9fa9459Szrj elfcpp::Elf_Xword flags_; 4517*a9fa9459Szrj // The order of this section in the output segment. 4518*a9fa9459Szrj Output_section_order order_; 4519*a9fa9459Szrj // The section index. 4520*a9fa9459Szrj unsigned int out_shndx_; 4521*a9fa9459Szrj // If there is a STT_SECTION for this output section in the normal 4522*a9fa9459Szrj // symbol table, this is the symbol index. This starts out as zero. 4523*a9fa9459Szrj // It is initialized in Layout::finalize() to be the index, or -1U 4524*a9fa9459Szrj // if there isn't one. 4525*a9fa9459Szrj unsigned int symtab_index_; 4526*a9fa9459Szrj // If there is a STT_SECTION for this output section in the dynamic 4527*a9fa9459Szrj // symbol table, this is the symbol index. This starts out as zero. 4528*a9fa9459Szrj // It is initialized in Layout::finalize() to be the index, or -1U 4529*a9fa9459Szrj // if there isn't one. 4530*a9fa9459Szrj unsigned int dynsym_index_; 4531*a9fa9459Szrj // The input sections. This will be empty in cases where we don't 4532*a9fa9459Szrj // need to keep track of them. 4533*a9fa9459Szrj Input_section_list input_sections_; 4534*a9fa9459Szrj // The offset of the first entry in input_sections_. 4535*a9fa9459Szrj off_t first_input_offset_; 4536*a9fa9459Szrj // The fill data. This is separate from input_sections_ because we 4537*a9fa9459Szrj // often will need fill sections without needing to keep track of 4538*a9fa9459Szrj // input sections. 4539*a9fa9459Szrj Fill_list fills_; 4540*a9fa9459Szrj // If the section requires postprocessing, this buffer holds the 4541*a9fa9459Szrj // section contents during relocation. 4542*a9fa9459Szrj unsigned char* postprocessing_buffer_; 4543*a9fa9459Szrj // Whether this output section needs a STT_SECTION symbol in the 4544*a9fa9459Szrj // normal symbol table. This will be true if there is a relocation 4545*a9fa9459Szrj // which needs it. 4546*a9fa9459Szrj bool needs_symtab_index_ : 1; 4547*a9fa9459Szrj // Whether this output section needs a STT_SECTION symbol in the 4548*a9fa9459Szrj // dynamic symbol table. This will be true if there is a dynamic 4549*a9fa9459Szrj // relocation which needs it. 4550*a9fa9459Szrj bool needs_dynsym_index_ : 1; 4551*a9fa9459Szrj // Whether the link field of this output section should point to the 4552*a9fa9459Szrj // normal symbol table. 4553*a9fa9459Szrj bool should_link_to_symtab_ : 1; 4554*a9fa9459Szrj // Whether the link field of this output section should point to the 4555*a9fa9459Szrj // dynamic symbol table. 4556*a9fa9459Szrj bool should_link_to_dynsym_ : 1; 4557*a9fa9459Szrj // Whether this section should be written after all the input 4558*a9fa9459Szrj // sections are complete. 4559*a9fa9459Szrj bool after_input_sections_ : 1; 4560*a9fa9459Szrj // Whether this section requires post processing after all 4561*a9fa9459Szrj // relocations have been applied. 4562*a9fa9459Szrj bool requires_postprocessing_ : 1; 4563*a9fa9459Szrj // Whether an input section was mapped to this output section 4564*a9fa9459Szrj // because of a SECTIONS clause in a linker script. 4565*a9fa9459Szrj bool found_in_sections_clause_ : 1; 4566*a9fa9459Szrj // Whether this section has an explicitly specified load address. 4567*a9fa9459Szrj bool has_load_address_ : 1; 4568*a9fa9459Szrj // True if the info_section_ field means the section index of the 4569*a9fa9459Szrj // section, false if it means the symbol index of the corresponding 4570*a9fa9459Szrj // section symbol. 4571*a9fa9459Szrj bool info_uses_section_index_ : 1; 4572*a9fa9459Szrj // True if input sections attached to this output section have to be 4573*a9fa9459Szrj // sorted according to a specified order. 4574*a9fa9459Szrj bool input_section_order_specified_ : 1; 4575*a9fa9459Szrj // True if the input sections attached to this output section may 4576*a9fa9459Szrj // need sorting. 4577*a9fa9459Szrj bool may_sort_attached_input_sections_ : 1; 4578*a9fa9459Szrj // True if the input sections attached to this output section must 4579*a9fa9459Szrj // be sorted. 4580*a9fa9459Szrj bool must_sort_attached_input_sections_ : 1; 4581*a9fa9459Szrj // True if the input sections attached to this output section have 4582*a9fa9459Szrj // already been sorted. 4583*a9fa9459Szrj bool attached_input_sections_are_sorted_ : 1; 4584*a9fa9459Szrj // True if this section holds relro data. 4585*a9fa9459Szrj bool is_relro_ : 1; 4586*a9fa9459Szrj // True if this is a small section. 4587*a9fa9459Szrj bool is_small_section_ : 1; 4588*a9fa9459Szrj // True if this is a large section. 4589*a9fa9459Szrj bool is_large_section_ : 1; 4590*a9fa9459Szrj // Whether code-fills are generated at write. 4591*a9fa9459Szrj bool generate_code_fills_at_write_ : 1; 4592*a9fa9459Szrj // Whether the entry size field should be zero. 4593*a9fa9459Szrj bool is_entsize_zero_ : 1; 4594*a9fa9459Szrj // Whether section offsets need adjustment due to relaxation. 4595*a9fa9459Szrj bool section_offsets_need_adjustment_ : 1; 4596*a9fa9459Szrj // Whether this is a NOLOAD section. 4597*a9fa9459Szrj bool is_noload_ : 1; 4598*a9fa9459Szrj // Whether this always keeps input section. 4599*a9fa9459Szrj bool always_keeps_input_sections_ : 1; 4600*a9fa9459Szrj // Whether this section has a fixed layout, for incremental update links. 4601*a9fa9459Szrj bool has_fixed_layout_ : 1; 4602*a9fa9459Szrj // True if we can add patch space to this section. 4603*a9fa9459Szrj bool is_patch_space_allowed_ : 1; 4604*a9fa9459Szrj // True if this output section goes into a unique segment. 4605*a9fa9459Szrj bool is_unique_segment_ : 1; 4606*a9fa9459Szrj // For SHT_TLS sections, the offset of this section relative to the base 4607*a9fa9459Szrj // of the TLS segment. 4608*a9fa9459Szrj uint64_t tls_offset_; 4609*a9fa9459Szrj // Additional segment flags, specified via linker plugin, when mapping some 4610*a9fa9459Szrj // input sections to unique segments. 4611*a9fa9459Szrj uint64_t extra_segment_flags_; 4612*a9fa9459Szrj // Segment alignment specified via linker plugin, when mapping some 4613*a9fa9459Szrj // input sections to unique segments. 4614*a9fa9459Szrj uint64_t segment_alignment_; 4615*a9fa9459Szrj // Saved checkpoint. 4616*a9fa9459Szrj Checkpoint_output_section* checkpoint_; 4617*a9fa9459Szrj // Fast lookup maps for merged and relaxed input sections. 4618*a9fa9459Szrj Output_section_lookup_maps* lookup_maps_; 4619*a9fa9459Szrj // List of available regions within the section, for incremental 4620*a9fa9459Szrj // update links. 4621*a9fa9459Szrj Free_list free_list_; 4622*a9fa9459Szrj // Method for filling chunks of free space. 4623*a9fa9459Szrj Output_fill* free_space_fill_; 4624*a9fa9459Szrj // Amount added as patch space for incremental linking. 4625*a9fa9459Szrj off_t patch_space_; 4626*a9fa9459Szrj }; 4627*a9fa9459Szrj 4628*a9fa9459Szrj // An output segment. PT_LOAD segments are built from collections of 4629*a9fa9459Szrj // output sections. Other segments typically point within PT_LOAD 4630*a9fa9459Szrj // segments, and are built directly as needed. 4631*a9fa9459Szrj // 4632*a9fa9459Szrj // NOTE: We want to use the copy constructor for this class. During 4633*a9fa9459Szrj // relaxation, we may try built the segments multiple times. We do 4634*a9fa9459Szrj // that by copying the original segment list before lay-out, doing 4635*a9fa9459Szrj // a trial lay-out and roll-back to the saved copied if we need to 4636*a9fa9459Szrj // to the lay-out again. 4637*a9fa9459Szrj 4638*a9fa9459Szrj class Output_segment 4639*a9fa9459Szrj { 4640*a9fa9459Szrj public: 4641*a9fa9459Szrj // Create an output segment, specifying the type and flags. 4642*a9fa9459Szrj Output_segment(elfcpp::Elf_Word, elfcpp::Elf_Word); 4643*a9fa9459Szrj 4644*a9fa9459Szrj // Return the virtual address. 4645*a9fa9459Szrj uint64_t vaddr()4646*a9fa9459Szrj vaddr() const 4647*a9fa9459Szrj { return this->vaddr_; } 4648*a9fa9459Szrj 4649*a9fa9459Szrj // Return the physical address. 4650*a9fa9459Szrj uint64_t paddr()4651*a9fa9459Szrj paddr() const 4652*a9fa9459Szrj { return this->paddr_; } 4653*a9fa9459Szrj 4654*a9fa9459Szrj // Return the segment type. 4655*a9fa9459Szrj elfcpp::Elf_Word type()4656*a9fa9459Szrj type() const 4657*a9fa9459Szrj { return this->type_; } 4658*a9fa9459Szrj 4659*a9fa9459Szrj // Return the segment flags. 4660*a9fa9459Szrj elfcpp::Elf_Word flags()4661*a9fa9459Szrj flags() const 4662*a9fa9459Szrj { return this->flags_; } 4663*a9fa9459Szrj 4664*a9fa9459Szrj // Return the memory size. 4665*a9fa9459Szrj uint64_t memsz()4666*a9fa9459Szrj memsz() const 4667*a9fa9459Szrj { return this->memsz_; } 4668*a9fa9459Szrj 4669*a9fa9459Szrj // Return the file size. 4670*a9fa9459Szrj off_t filesz()4671*a9fa9459Szrj filesz() const 4672*a9fa9459Szrj { return this->filesz_; } 4673*a9fa9459Szrj 4674*a9fa9459Szrj // Return the file offset. 4675*a9fa9459Szrj off_t offset()4676*a9fa9459Szrj offset() const 4677*a9fa9459Szrj { return this->offset_; } 4678*a9fa9459Szrj 4679*a9fa9459Szrj // Whether this is a segment created to hold large data sections. 4680*a9fa9459Szrj bool is_large_data_segment()4681*a9fa9459Szrj is_large_data_segment() const 4682*a9fa9459Szrj { return this->is_large_data_segment_; } 4683*a9fa9459Szrj 4684*a9fa9459Szrj // Record that this is a segment created to hold large data 4685*a9fa9459Szrj // sections. 4686*a9fa9459Szrj void set_is_large_data_segment()4687*a9fa9459Szrj set_is_large_data_segment() 4688*a9fa9459Szrj { this->is_large_data_segment_ = true; } 4689*a9fa9459Szrj 4690*a9fa9459Szrj bool is_unique_segment()4691*a9fa9459Szrj is_unique_segment() const 4692*a9fa9459Szrj { return this->is_unique_segment_; } 4693*a9fa9459Szrj 4694*a9fa9459Szrj // Mark segment as unique, happens when linker plugins request that 4695*a9fa9459Szrj // certain input sections be mapped to unique segments. 4696*a9fa9459Szrj void set_is_unique_segment()4697*a9fa9459Szrj set_is_unique_segment() 4698*a9fa9459Szrj { this->is_unique_segment_ = true; } 4699*a9fa9459Szrj 4700*a9fa9459Szrj // Return the maximum alignment of the Output_data. 4701*a9fa9459Szrj uint64_t 4702*a9fa9459Szrj maximum_alignment(); 4703*a9fa9459Szrj 4704*a9fa9459Szrj // Add the Output_section OS to this PT_LOAD segment. SEG_FLAGS is 4705*a9fa9459Szrj // the segment flags to use. 4706*a9fa9459Szrj void 4707*a9fa9459Szrj add_output_section_to_load(Layout* layout, Output_section* os, 4708*a9fa9459Szrj elfcpp::Elf_Word seg_flags); 4709*a9fa9459Szrj 4710*a9fa9459Szrj // Add the Output_section OS to this non-PT_LOAD segment. SEG_FLAGS 4711*a9fa9459Szrj // is the segment flags to use. 4712*a9fa9459Szrj void 4713*a9fa9459Szrj add_output_section_to_nonload(Output_section* os, 4714*a9fa9459Szrj elfcpp::Elf_Word seg_flags); 4715*a9fa9459Szrj 4716*a9fa9459Szrj // Remove an Output_section from this segment. It is an error if it 4717*a9fa9459Szrj // is not present. 4718*a9fa9459Szrj void 4719*a9fa9459Szrj remove_output_section(Output_section* os); 4720*a9fa9459Szrj 4721*a9fa9459Szrj // Add an Output_data (which need not be an Output_section) to the 4722*a9fa9459Szrj // start of this segment. 4723*a9fa9459Szrj void 4724*a9fa9459Szrj add_initial_output_data(Output_data*); 4725*a9fa9459Szrj 4726*a9fa9459Szrj // Return true if this segment has any sections which hold actual 4727*a9fa9459Szrj // data, rather than being a BSS section. 4728*a9fa9459Szrj bool 4729*a9fa9459Szrj has_any_data_sections() const; 4730*a9fa9459Szrj 4731*a9fa9459Szrj // Whether this segment has a dynamic relocs. 4732*a9fa9459Szrj bool 4733*a9fa9459Szrj has_dynamic_reloc() const; 4734*a9fa9459Szrj 4735*a9fa9459Szrj // Return the first section. 4736*a9fa9459Szrj Output_section* 4737*a9fa9459Szrj first_section() const; 4738*a9fa9459Szrj 4739*a9fa9459Szrj // Return the address of the first section. 4740*a9fa9459Szrj uint64_t first_section_load_address()4741*a9fa9459Szrj first_section_load_address() const 4742*a9fa9459Szrj { 4743*a9fa9459Szrj const Output_section* os = this->first_section(); 4744*a9fa9459Szrj return os->has_load_address() ? os->load_address() : os->address(); 4745*a9fa9459Szrj } 4746*a9fa9459Szrj 4747*a9fa9459Szrj // Return whether the addresses have been set already. 4748*a9fa9459Szrj bool are_addresses_set()4749*a9fa9459Szrj are_addresses_set() const 4750*a9fa9459Szrj { return this->are_addresses_set_; } 4751*a9fa9459Szrj 4752*a9fa9459Szrj // Set the addresses. 4753*a9fa9459Szrj void set_addresses(uint64_t vaddr,uint64_t paddr)4754*a9fa9459Szrj set_addresses(uint64_t vaddr, uint64_t paddr) 4755*a9fa9459Szrj { 4756*a9fa9459Szrj this->vaddr_ = vaddr; 4757*a9fa9459Szrj this->paddr_ = paddr; 4758*a9fa9459Szrj this->are_addresses_set_ = true; 4759*a9fa9459Szrj } 4760*a9fa9459Szrj 4761*a9fa9459Szrj // Update the flags for the flags of an output section added to this 4762*a9fa9459Szrj // segment. 4763*a9fa9459Szrj void update_flags_for_output_section(elfcpp::Elf_Xword flags)4764*a9fa9459Szrj update_flags_for_output_section(elfcpp::Elf_Xword flags) 4765*a9fa9459Szrj { 4766*a9fa9459Szrj // The ELF ABI specifies that a PT_TLS segment should always have 4767*a9fa9459Szrj // PF_R as the flags. 4768*a9fa9459Szrj if (this->type() != elfcpp::PT_TLS) 4769*a9fa9459Szrj this->flags_ |= flags; 4770*a9fa9459Szrj } 4771*a9fa9459Szrj 4772*a9fa9459Szrj // Set the segment flags. This is only used if we have a PHDRS 4773*a9fa9459Szrj // clause which explicitly specifies the flags. 4774*a9fa9459Szrj void set_flags(elfcpp::Elf_Word flags)4775*a9fa9459Szrj set_flags(elfcpp::Elf_Word flags) 4776*a9fa9459Szrj { this->flags_ = flags; } 4777*a9fa9459Szrj 4778*a9fa9459Szrj // Set the address of the segment to ADDR and the offset to *POFF 4779*a9fa9459Szrj // and set the addresses and offsets of all contained output 4780*a9fa9459Szrj // sections accordingly. Set the section indexes of all contained 4781*a9fa9459Szrj // output sections starting with *PSHNDX. If RESET is true, first 4782*a9fa9459Szrj // reset the addresses of the contained sections. Return the 4783*a9fa9459Szrj // address of the immediately following segment. Update *POFF and 4784*a9fa9459Szrj // *PSHNDX. This should only be called for a PT_LOAD segment. 4785*a9fa9459Szrj uint64_t 4786*a9fa9459Szrj set_section_addresses(const Target*, Layout*, bool reset, uint64_t addr, 4787*a9fa9459Szrj unsigned int* increase_relro, bool* has_relro, 4788*a9fa9459Szrj off_t* poff, unsigned int* pshndx); 4789*a9fa9459Szrj 4790*a9fa9459Szrj // Set the minimum alignment of this segment. This may be adjusted 4791*a9fa9459Szrj // upward based on the section alignments. 4792*a9fa9459Szrj void set_minimum_p_align(uint64_t align)4793*a9fa9459Szrj set_minimum_p_align(uint64_t align) 4794*a9fa9459Szrj { 4795*a9fa9459Szrj if (align > this->min_p_align_) 4796*a9fa9459Szrj this->min_p_align_ = align; 4797*a9fa9459Szrj } 4798*a9fa9459Szrj 4799*a9fa9459Szrj // Set the offset of this segment based on the section. This should 4800*a9fa9459Szrj // only be called for a non-PT_LOAD segment. 4801*a9fa9459Szrj void 4802*a9fa9459Szrj set_offset(unsigned int increase); 4803*a9fa9459Szrj 4804*a9fa9459Szrj // Set the TLS offsets of the sections contained in the PT_TLS segment. 4805*a9fa9459Szrj void 4806*a9fa9459Szrj set_tls_offsets(); 4807*a9fa9459Szrj 4808*a9fa9459Szrj // Return the number of output sections. 4809*a9fa9459Szrj unsigned int 4810*a9fa9459Szrj output_section_count() const; 4811*a9fa9459Szrj 4812*a9fa9459Szrj // Return the section attached to the list segment with the lowest 4813*a9fa9459Szrj // load address. This is used when handling a PHDRS clause in a 4814*a9fa9459Szrj // linker script. 4815*a9fa9459Szrj Output_section* 4816*a9fa9459Szrj section_with_lowest_load_address() const; 4817*a9fa9459Szrj 4818*a9fa9459Szrj // Write the segment header into *OPHDR. 4819*a9fa9459Szrj template<int size, bool big_endian> 4820*a9fa9459Szrj void 4821*a9fa9459Szrj write_header(elfcpp::Phdr_write<size, big_endian>*); 4822*a9fa9459Szrj 4823*a9fa9459Szrj // Write the section headers of associated sections into V. 4824*a9fa9459Szrj template<int size, bool big_endian> 4825*a9fa9459Szrj unsigned char* 4826*a9fa9459Szrj write_section_headers(const Layout*, const Stringpool*, unsigned char* v, 4827*a9fa9459Szrj unsigned int* pshndx) const; 4828*a9fa9459Szrj 4829*a9fa9459Szrj // Print the output sections in the map file. 4830*a9fa9459Szrj void 4831*a9fa9459Szrj print_sections_to_mapfile(Mapfile*) const; 4832*a9fa9459Szrj 4833*a9fa9459Szrj private: 4834*a9fa9459Szrj typedef std::vector<Output_data*> Output_data_list; 4835*a9fa9459Szrj 4836*a9fa9459Szrj // Find the maximum alignment in an Output_data_list. 4837*a9fa9459Szrj static uint64_t 4838*a9fa9459Szrj maximum_alignment_list(const Output_data_list*); 4839*a9fa9459Szrj 4840*a9fa9459Szrj // Return whether the first data section is a relro section. 4841*a9fa9459Szrj bool 4842*a9fa9459Szrj is_first_section_relro() const; 4843*a9fa9459Szrj 4844*a9fa9459Szrj // Set the section addresses in an Output_data_list. 4845*a9fa9459Szrj uint64_t 4846*a9fa9459Szrj set_section_list_addresses(Layout*, bool reset, Output_data_list*, 4847*a9fa9459Szrj uint64_t addr, off_t* poff, unsigned int* pshndx, 4848*a9fa9459Szrj bool* in_tls); 4849*a9fa9459Szrj 4850*a9fa9459Szrj // Return the number of Output_sections in an Output_data_list. 4851*a9fa9459Szrj unsigned int 4852*a9fa9459Szrj output_section_count_list(const Output_data_list*) const; 4853*a9fa9459Szrj 4854*a9fa9459Szrj // Return whether an Output_data_list has a dynamic reloc. 4855*a9fa9459Szrj bool 4856*a9fa9459Szrj has_dynamic_reloc_list(const Output_data_list*) const; 4857*a9fa9459Szrj 4858*a9fa9459Szrj // Find the section with the lowest load address in an 4859*a9fa9459Szrj // Output_data_list. 4860*a9fa9459Szrj void 4861*a9fa9459Szrj lowest_load_address_in_list(const Output_data_list* pdl, 4862*a9fa9459Szrj Output_section** found, 4863*a9fa9459Szrj uint64_t* found_lma) const; 4864*a9fa9459Szrj 4865*a9fa9459Szrj // Find the first and last entries by address. 4866*a9fa9459Szrj void 4867*a9fa9459Szrj find_first_and_last_list(const Output_data_list* pdl, 4868*a9fa9459Szrj const Output_data** pfirst, 4869*a9fa9459Szrj const Output_data** plast) const; 4870*a9fa9459Szrj 4871*a9fa9459Szrj // Write the section headers in the list into V. 4872*a9fa9459Szrj template<int size, bool big_endian> 4873*a9fa9459Szrj unsigned char* 4874*a9fa9459Szrj write_section_headers_list(const Layout*, const Stringpool*, 4875*a9fa9459Szrj const Output_data_list*, unsigned char* v, 4876*a9fa9459Szrj unsigned int* pshdx) const; 4877*a9fa9459Szrj 4878*a9fa9459Szrj // Print a section list to the mapfile. 4879*a9fa9459Szrj void 4880*a9fa9459Szrj print_section_list_to_mapfile(Mapfile*, const Output_data_list*) const; 4881*a9fa9459Szrj 4882*a9fa9459Szrj // NOTE: We want to use the copy constructor. Currently, shallow copy 4883*a9fa9459Szrj // works for us so we do not need to write our own copy constructor. 4884*a9fa9459Szrj 4885*a9fa9459Szrj // The list of output data attached to this segment. 4886*a9fa9459Szrj Output_data_list output_lists_[ORDER_MAX]; 4887*a9fa9459Szrj // The segment virtual address. 4888*a9fa9459Szrj uint64_t vaddr_; 4889*a9fa9459Szrj // The segment physical address. 4890*a9fa9459Szrj uint64_t paddr_; 4891*a9fa9459Szrj // The size of the segment in memory. 4892*a9fa9459Szrj uint64_t memsz_; 4893*a9fa9459Szrj // The maximum section alignment. The is_max_align_known_ field 4894*a9fa9459Szrj // indicates whether this has been finalized. 4895*a9fa9459Szrj uint64_t max_align_; 4896*a9fa9459Szrj // The required minimum value for the p_align field. This is used 4897*a9fa9459Szrj // for PT_LOAD segments. Note that this does not mean that 4898*a9fa9459Szrj // addresses should be aligned to this value; it means the p_paddr 4899*a9fa9459Szrj // and p_vaddr fields must be congruent modulo this value. For 4900*a9fa9459Szrj // non-PT_LOAD segments, the dynamic linker works more efficiently 4901*a9fa9459Szrj // if the p_align field has the more conventional value, although it 4902*a9fa9459Szrj // can align as needed. 4903*a9fa9459Szrj uint64_t min_p_align_; 4904*a9fa9459Szrj // The offset of the segment data within the file. 4905*a9fa9459Szrj off_t offset_; 4906*a9fa9459Szrj // The size of the segment data in the file. 4907*a9fa9459Szrj off_t filesz_; 4908*a9fa9459Szrj // The segment type; 4909*a9fa9459Szrj elfcpp::Elf_Word type_; 4910*a9fa9459Szrj // The segment flags. 4911*a9fa9459Szrj elfcpp::Elf_Word flags_; 4912*a9fa9459Szrj // Whether we have finalized max_align_. 4913*a9fa9459Szrj bool is_max_align_known_ : 1; 4914*a9fa9459Szrj // Whether vaddr and paddr were set by a linker script. 4915*a9fa9459Szrj bool are_addresses_set_ : 1; 4916*a9fa9459Szrj // Whether this segment holds large data sections. 4917*a9fa9459Szrj bool is_large_data_segment_ : 1; 4918*a9fa9459Szrj // Whether this was marked as a unique segment via a linker plugin. 4919*a9fa9459Szrj bool is_unique_segment_ : 1; 4920*a9fa9459Szrj }; 4921*a9fa9459Szrj 4922*a9fa9459Szrj } // End namespace gold. 4923*a9fa9459Szrj 4924*a9fa9459Szrj #endif // !defined(GOLD_OUTPUT_H) 4925