diff options
author | Chris Johns <chrisj@rtems.org> | 2012-12-15 22:44:58 +1100 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2012-12-15 22:44:58 +1100 |
commit | 7c02253d5df3347a0ff85e43fd2a9dca0955b55f (patch) | |
tree | 11712ee20d60770cba1c54031c21be9b2c22e954 | |
parent | b0133b8592fcfca819f73e8663c3375dc27fb274 (diff) |
i386 related fixes
Fix the size of the section calculated in image::lay_out. It did not
correctly adjust for alignment. Make the sections being written
correctly align.
-rw-r--r-- | rld-elf.cpp | 16 | ||||
-rw-r--r-- | rld-rap.cpp | 97 | ||||
-rw-r--r-- | rld-resolver.cpp | 3 | ||||
-rw-r--r-- | rld-symbols.cpp | 1 |
4 files changed, 70 insertions, 47 deletions
diff --git a/rld-elf.cpp b/rld-elf.cpp index 21962a1..5abab28 100644 --- a/rld-elf.cpp +++ b/rld-elf.cpp @@ -186,6 +186,13 @@ namespace rld if (!data_) libelf_error ("elf_getdata: " + name_ + '(' + file_.name () + ')'); } + + if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) + std::cout << "elf::section: " << name () + << " size=" << size () + << " align=" << shdr.sh_addralign + << " flags=0x" << std::hex << flags () << std::dec + << std::endl; } section::section (const section& orig) @@ -729,7 +736,6 @@ namespace rld file::get_sections (sections& filtered_secs, unsigned int type) { load_sections (); - filtered_secs.clear (); for (section_table::iterator si = secs.begin (); si != secs.end (); ++si) @@ -794,11 +800,7 @@ namespace rld symbols::symbol sym (s, name, esym); if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - { - std::cout << "elf:symbol: "; - sym.output (std::cout); - std::cout << std::endl; - } + std::cout << "elf:symbol: " << sym << std::endl; symbols.push_back (sym); } @@ -953,7 +955,7 @@ namespace rld << " type:" << GELF_R_TYPE (erel.r_info) << std::endl; - const symbols::symbol& sym = get_symbol (erel.r_info); + const symbols::symbol& sym = get_symbol (GELF_R_SYM (erel.r_info)); relocation reloc (sym, erel.r_offset, erel.r_info); diff --git a/rld-rap.cpp b/rld-rap.cpp index 17cd236..3733f79 100644 --- a/rld-rap.cpp +++ b/rld-rap.cpp @@ -165,7 +165,7 @@ namespace rld external (const uint32_t name, const sections sec, const uint32_t value, - const uint32_t info); + const uint32_t data); /** * Copy constructor. @@ -268,11 +268,19 @@ namespace rld const std::string& fini); /** - * Write the sections to the compressed output file. + * Write the sections to the compressed output file. The file sections + * are used to ensure the alignment. The offset is used to ensure the + * alignment of the first section of the object when it is written. + * + * @param comp The compressor. + * @param obj The object file the sections are part of. + * @param secs The container of file sections to write. + * @param offset The current offset in the RAP section. */ void write (compress::compressor& comp, files::object& obj, - const files::sections& secs); + const files::sections& secs, + uint32_t& offset); /** * Write the external symbols. @@ -429,11 +437,8 @@ namespace rld { if (sec.size) { - if (align == 0) + if (align < sec.align) align = sec.align; - else if (align != sec.align) - throw rld::error ("Alignments do not match for section '" + name + "'", - "rap::section"); if (size && (align == 0)) throw rld::error ("Invalid alignment '" + name + "'", @@ -450,11 +455,8 @@ namespace rld void section::set_alignment (const section& sec) { - if (align == 0) + if (align < sec.align) align = sec.align; - else if (align != sec.align) - throw rld::error ("Alignments do not match for section '" + name + "'", - "rap::section"); } void @@ -505,15 +507,12 @@ namespace rld void section_merge::operator () (const files::section& fsec) { - if (sec.align == 0) + if (sec.align < fsec.alignment) sec.align = fsec.alignment; - else if (sec.align != fsec.alignment) - throw rld::error ("Alignments do not match for section '" + sec.name + "'", - "rap::section"); uint32_t offset = align_offset (sec.size, 0, sec.align); - if (1 || rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) + if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) std::cout << "rap:section-merge: relocs=" << fsec.relocs.size () << " offset=" << offset << " fsec.name=" << fsec.name @@ -535,13 +534,14 @@ namespace rld { const files::relocation& freloc = *fri; - if (1 || rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) + if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) std::cout << " " << std::setw (2) << sec.relocs.size () << '/' << std::setw (2) << rc << std::hex << ": reloc.info=0x" << freloc.info << std::dec << " reloc.offset=" << freloc.offset << " reloc.addend=" << freloc.addend << " reloc.symtype=" << freloc.symtype + << " reloc.symsect=" << freloc.symsect << std::endl; if (freloc.symtype == STT_NOTYPE) @@ -626,7 +626,7 @@ namespace rld std::for_each (bss.begin (), bss.end (), section_merge (*this, secs[rap_bss])); - if (1 || rld::verbose () >= RLD_VERBOSE_TRACE) + if (rld::verbose () >= RLD_VERBOSE_TRACE) { std::cout << "rap:object: " << obj.name ().full () << std::endl; output ("text", secs[rap_text].size, text); @@ -758,7 +758,7 @@ namespace rld relocs_size += obj.get_relocations (); } - if (1 || rld::verbose () >= RLD_VERBOSE_INFO) + if (rld::verbose () >= RLD_VERBOSE_INFO) { uint32_t total = (sec_size[rap_text] + sec_size[rap_data] + sec_size[rap_data] + sec_size[rap_bss] + @@ -833,6 +833,7 @@ namespace rld image& img; compress::compressor& comp; sections sec; + uint32_t offset; }; section_writer::section_writer (image& img, @@ -840,7 +841,8 @@ namespace rld sections sec) : img (img), comp (comp), - sec (sec) + sec (sec), + offset (0) { } @@ -853,22 +855,22 @@ namespace rld switch (sec) { case rap_text: - img.write (comp, obj.obj, obj.text); + img.write (comp, obj.obj, obj.text, offset); break; case rap_const: - img.write (comp, obj.obj, obj.const_); + img.write (comp, obj.obj, obj.const_, offset); break; case rap_ctor: - img.write (comp, obj.obj, obj.ctor); + img.write (comp, obj.obj, obj.ctor, offset); break; case rap_dtor: - img.write (comp, obj.obj, obj.dtor); + img.write (comp, obj.obj, obj.dtor, offset); break; case rap_data: - img.write (comp, obj.obj, obj.data); + img.write (comp, obj.obj, obj.data, offset); + break; + default: break; - default: - break; } } @@ -929,9 +931,9 @@ namespace rld void image::write (compress::compressor& comp, files::object& obj, - const files::sections& secs) + const files::sections& secs, + uint32_t& offset) { - uint32_t offset = 0; uint32_t size = 0; obj.open (); @@ -961,15 +963,20 @@ namespace rld comp.write (obj, sec.offset, sec.size); - if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << " offset=" << offset - << " padding=" << (offset - unaligned_offset) << std::endl; + if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) + std::cout << " sec: " << sec.name + << " size=" << sec.size + << " offset=" << offset + << " align=" << sec.alignment + << " padding=" << (offset - unaligned_offset) << std::endl; size = sec.size; } + offset += size; + if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << " -- size=" << offset << std::endl; + std::cout << " total size=" << offset << std::endl; obj.end (); } @@ -990,6 +997,18 @@ namespace rld ++ei) { const external& ext = *ei; + + if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) + std::cout << "rap:externs: name=" << &strtab[ext.name - 2] << " (" << ext.name << ')' + << " section=" << section_names[ext.sec] + << " data=" << ext.data + << " value=0x" << std::hex << ext.value << std::dec + << std::endl; + + if ((ext.data & 0xffff0000) != 0) + throw rld::error ("Data value has data in bits higher than 15", + "rap::write-externs"); + comp << (uint32_t) ((ext.sec << 16) | ext.data) << ext.name << ext.value; @@ -1005,9 +1024,10 @@ namespace rld uint32_t sr = 0; uint32_t header; - if (1 || rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) - std::cout << "rep:relocation: section:" << section_names[s] + if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) + std::cout << "rap:relocation: section:" << section_names[s] << " relocs=" << count + << " rela=" << (char*) (sec_rela[s] ? "yes" : "no") << std::endl; header = count; @@ -1024,7 +1044,7 @@ namespace rld relocations& relocs = sec.relocs; uint32_t rc = 0; - if (1 || rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) + if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) std::cout << " relocs=" << sec.relocs.size () << " sec.offset=" << sec.offset << " sec.size=" << sec.size @@ -1055,7 +1075,7 @@ namespace rld write_addend = true; - if (1 || rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) + if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) std::cout << " " << std::setw (2) << sr << '/' << std::setw (2) << rc <<": rsym: sect=" << section_names[reloc.symsect] << " sec.offset=" << obj.secs[reloc.symsect].offset @@ -1094,7 +1114,7 @@ namespace rld } } - if (1 || rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) + if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG) { std::cout << " " << std::setw (2) << sr << '/' << std::setw (2) << rc @@ -1160,6 +1180,7 @@ namespace rld void image::update_section (int index, const section& sec) { + sec_size[index] = align_offset (sec_size[index], 0, sec.align); sec_size[index] += sec.size; sec_align[index] = sec.align; sec_rela[index] = sec.rela; diff --git a/rld-resolver.cpp b/rld-resolver.cpp index abb7890..93bc9da 100644 --- a/rld-resolver.cpp +++ b/rld-resolver.cpp @@ -88,8 +88,7 @@ namespace rld { esi = symbols.find (urs.name ()); if (esi == symbols.end ()) - throw rld::error ("symbol referenced in '" + name + - "' not found: " + urs.name (), "resolving"); + throw rld::error ("symbol not found: " + urs.name (), name); base = false; } diff --git a/rld-symbols.cpp b/rld-symbols.cpp index 982ef4d..c35e218 100644 --- a/rld-symbols.cpp +++ b/rld-symbols.cpp @@ -250,6 +250,7 @@ namespace rld out << std::setw (4) << index_ << ' ' << binding << ' ' << type + << ' ' << std::setw(2) << es.st_shndx << " 0x" << std::setw (8) << std::setfill ('0') << std::hex << es.st_value << std::dec << std::setfill (' ') |