diff options
author | Ian Lance Taylor <iant@google.com> | 2006-11-14 19:21:05 +0000 |
---|---|---|
committer | Ian Lance Taylor <iant@google.com> | 2006-11-14 19:21:05 +0000 |
commit | dbe717effbdf31236088837f4686fd5ad5e71893 (patch) | |
tree | fd5ed267334d62fadcaf7ff7132c0a7287553ed8 /gold/layout.cc | |
parent | 6c73cbb1d9a26d1c4d9bd5464832846b7c049b9d (diff) | |
download | gdb-dbe717effbdf31236088837f4686fd5ad5e71893.zip gdb-dbe717effbdf31236088837f4686fd5ad5e71893.tar.gz gdb-dbe717effbdf31236088837f4686fd5ad5e71893.tar.bz2 |
More dynamic object support, initial scripting support.
Diffstat (limited to 'gold/layout.cc')
-rw-r--r-- | gold/layout.cc | 74 |
1 files changed, 67 insertions, 7 deletions
diff --git a/gold/layout.cc b/gold/layout.cc index e969a80..bcb1029 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -355,13 +355,30 @@ Layout::find_first_load_seg() off_t Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab) { + const int size = input_objects->target()->get_size(); + + Output_segment* phdr_seg = NULL; if (input_objects->any_dynamic()) { - // If there are any dynamic objects in the link, then we need - // some additional segments: PT_PHDRS, PT_INTERP, and - // PT_DYNAMIC. We also need to finalize the dynamic symbol - // table and create the dynamic hash table. - abort(); + // There was a dynamic object in the link. We need to create + // some information for the dynamic linker. + + // Create the PT_PHDR segment which will hold the program + // headers. + phdr_seg = new Output_segment(elfcpp::PT_PHDR, elfcpp::PF_R); + this->segment_list_.push_back(phdr_seg); + + // Create the dynamic symbol table, including the hash table, + // the dynamic relocations, and the version sections. + this->create_dynamic_symtab(size, symtab); + + // Create the .dynamic section to hold the dynamic data, and put + // it in a PT_DYNAMIC segment. + this->create_dynamic_section(); + + // Create the .interp section to hold the name of the + // interpreter, and put it in a PT_INTERP segment. + this->create_interp(input_objects->target()); } // FIXME: Handle PT_GNU_STACK. @@ -369,14 +386,14 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab) Output_segment* load_seg = this->find_first_load_seg(); // Lay out the segment headers. - int size = input_objects->target()->get_size(); bool big_endian = input_objects->target()->is_big_endian(); Output_segment_headers* segment_headers; segment_headers = new Output_segment_headers(size, big_endian, this->segment_list_); load_seg->add_initial_output_data(segment_headers); this->special_output_list_.push_back(segment_headers); - // FIXME: Attach them to PT_PHDRS if necessary. + if (phdr_seg != NULL) + phdr_seg->add_initial_output_data(segment_headers); // Lay out the file header. Output_file_header* file_header; @@ -736,6 +753,49 @@ Layout::create_shdrs(int size, bool big_endian, off_t* poff) return oshdrs; } +// Create the dynamic symbol table. + +void +Layout::create_dynamic_symtab(int, Symbol_table*) +{ + abort(); +} + +// Create the .dynamic section and PT_DYNAMIC segment. + +void +Layout::create_dynamic_section() +{ + abort(); +} + +// Create the .interp section and PT_INTERP segment. + +void +Layout::create_interp(const Target* target) +{ + const char* interp = this->options_.dynamic_linker(); + if (interp == NULL) + { + interp = target->dynamic_linker(); + assert(interp != NULL); + } + + size_t len = strlen(interp) + 1; + + Output_section_data* odata = new Output_data_const(interp, len, 1); + + const char* interp_name = this->namepool_.add(".interp", NULL); + Output_section* osec = this->make_output_section(interp_name, + elfcpp::SHT_PROGBITS, + elfcpp::SHF_ALLOC); + osec->add_output_section_data(odata); + + Output_segment* oseg = new Output_segment(elfcpp::PT_INTERP, elfcpp::PF_R); + this->segment_list_.push_back(oseg); + oseg->add_initial_output_section(osec, elfcpp::PF_R); +} + // The mapping of .gnu.linkonce section names to real section names. #define MAPPING_INIT(f, t) { f, sizeof(f) - 1, t, sizeof(t) - 1 } |