From d628321500c7846622275ecdf88e8f7229822fa1 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 26 Jul 2013 17:45:01 +0800 Subject: Add object file details to RAP format This change added the object file details to the RAP format so aid debugging support. The information can be optionally stripped for production images not needed this information if space is an issue,with '--rap-strip' assigned to rtems-ld. --- rld-rap.cpp | 149 ++++++++++++++++++++++++++++++++++++++++++++- rld-rap.h | 5 ++ rtems-ld.cpp | 7 +++ rtems-rapper.cpp | 182 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 337 insertions(+), 6 deletions(-) diff --git a/rld-rap.cpp b/rld-rap.cpp index 033234b..e1365b3 100644 --- a/rld-rap.cpp +++ b/rld-rap.cpp @@ -41,6 +41,12 @@ namespace rld { namespace rap { + + /** + * Output details or not. + */ + bool add_obj_details = true; + /** * The names of the RAP sections. */ @@ -147,6 +153,24 @@ namespace rld */ typedef std::vector < int > osecindexes; + /** + * Section detail will be written into RAP file + */ + struct section_detail + { + uint32_t name; //< The offset in the strtable. + uint32_t offset; //< The offset in the rap section. + uint32_t id; //< The rap id. + + /* Constructor */ + section_detail (uint32_t name, uint32_t offset, uint32_t id); + }; + + /* + * A container of section detail + */ + typedef std::list < section_detail > section_details; + /** * The RAP section data. */ @@ -368,6 +392,11 @@ namespace rld */ void write_relocations (compress::compressor& comp); + /** + * Write the details of the files. + */ + void write_details (compress::compressor& comp); + /** * The total number of relocations for a specific RAP section in the * image. @@ -450,6 +479,15 @@ namespace rld { } + section_detail::section_detail (uint32_t name, + uint32_t offset, + uint32_t id) + : name (name), + offset (offset), + id (id) + { + } + osection::osection (const std::string& name, uint32_t offset, uint32_t size, @@ -1033,6 +1071,18 @@ namespace rld << (uint32_t) strtab.size () + 1 << (uint32_t) 0; + /* + * Output file details + */ + if (add_obj_details) + { + write_details (comp); + } + else + { + comp << (uint32_t)0; /* No file details */ + } + /* * The sections. */ @@ -1379,6 +1429,103 @@ namespace rld } } + void image::write_details (compress::compressor& comp) + { + + std::string strtable; + uint32_t pos = 0; + + section_details s_details; + + if (rld::verbose () >= RLD_VERBOSE_TRACE) + { + std::cout << "rap:file details" << std::endl + << " total " << objs.size () <<" files" << std::endl; + } + + comp << (uint32_t)(objs.size ()); + + for (objects::iterator oi = objs.begin (); + oi != objs.end (); + ++oi) + { + object& obj = *oi; + + /* obj full name */ + strtable += obj.obj.name ().full (); + strtable += '\0'; + } + + pos = strtable.length (); + + uint32_t sec_num = 0; + for (objects::iterator oi = objs.begin (); + oi != objs.end (); + ++oi) + { + object& obj = *oi; + + if (rld::verbose () >= RLD_VERBOSE_TRACE) + std::cout << "file:" << obj.obj.name ().full () << std::endl; + + for (int s = 0; s < rap_secs; ++s) + { + section& sec = obj.secs[s]; + + if (rld::verbose () >= RLD_VERBOSE_TRACE) + { + std::cout << "rap:section: " << sec.name << " " + "offset= " << sec.offset << std::endl; + } + + for (size_t si = 0; si < sec.osindexes.size (); ++si) + { + const osection& osec = sec.get_osection (sec.osindexes[si]); + + strtable += osec.name; + strtable += '\0'; + + /* sec.offset + osec.offset is the offset in the rap section */ + s_details.push_back (section_detail (pos, sec.offset + osec.offset, s)); + + pos = strtable.length (); + + if (rld::verbose () >= RLD_VERBOSE_TRACE) + { + std::cout << "osec.name=" << osec.name << " " + << "osec.offset=" << osec.offset << " " + << "osec.size=" << osec.size << std::endl; + } + } + } + + /* Output section numbers*/ + comp << (uint32_t)((s_details.size () - sec_num)); + if (rld::verbose () >= RLD_VERBOSE_TRACE) + std::cout << "sec_num:" << s_details.size () - sec_num << std::endl; + sec_num = s_details.size (); + } + + comp << (uint32_t)(strtable.size ()); + if (rld::verbose () >= RLD_VERBOSE_TRACE) + std::cout << "total detail size:" << strtable.size () << std::endl; + + comp << strtable; + + for (section_details::const_iterator si = s_details.begin (); + si != s_details.end (); + ++si) + { + const section_detail& sec_detail = *si; + comp << (uint32_t)(sec_detail.name); + + if (sec_detail.id > 0xf) + std::cout << "Out max rap section id 15\n" << std::endl; + + comp << (uint32_t)((sec_detail.id << 28) | sec_detail.offset); + } + } + uint32_t image::get_relocations (int sec) const { @@ -1450,7 +1597,7 @@ namespace rld { std::string header; - header = "RAP,00000000,0001,LZ77,00000000\n"; + header = "RAP,00000000,0002,LZ77,00000000\n"; app.write (header.c_str (), header.size ()); compress::compressor compressor (app, 2 * 1024); diff --git a/rld-rap.h b/rld-rap.h index df74bbe..b612e49 100644 --- a/rld-rap.h +++ b/rld-rap.h @@ -31,6 +31,11 @@ namespace rld { namespace rap { + /** + * Output details or not. + */ + extern bool add_obj_details; + /** * The RAP relocation bit masks. */ diff --git a/rtems-ld.cpp b/rtems-ld.cpp index e0dd332..d5bc1de 100644 --- a/rtems-ld.cpp +++ b/rtems-ld.cpp @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -69,6 +70,7 @@ static struct option rld_opts[] = { { "exec-prefix", required_argument, NULL, 'E' }, { "march", required_argument, NULL, 'a' }, { "mcpu", required_argument, NULL, 'c' }, + { "rap-strip", no_argument, NULL, 'S' }, { NULL, 0, NULL, 0 } }; @@ -109,6 +111,7 @@ usage (int exit_code) << " -E prefix : the RTEMS tool prefix (also --exec-prefix)" << std::endl << " -a march : machine architecture (also --march)" << std::endl << " -c cpu : machine architecture's CPU (also --mcpu)" << std::endl + << " -S : do not include file details (also --rap-strip)" << std::endl << " -Wl,opts : link compatible flags, ignored" << std::endl << "Output Formats:" << std::endl << " rap - RTEMS application (LZ77, single image)" << std::endl @@ -274,6 +277,10 @@ main (int argc, char* argv[]) base_name = optarg; break; + case 'S': + rld::rap::add_obj_details = false; + break; + case 'W': /* ignore linker compatiable flags */ break; diff --git a/rtems-rapper.cpp b/rtems-rapper.cpp index af7ba81..fbee1d1 100644 --- a/rtems-rapper.cpp +++ b/rtems-rapper.cpp @@ -56,6 +56,19 @@ */ namespace rap { + /** + * The names of the RAP sections. + */ + static const char* section_names[6] = + { + ".text", + ".const", + ".ctor", + ".dtor", + ".data", + ".bss" + }; + /** * A relocation record. */ @@ -107,6 +120,42 @@ namespace rap void load_relocs (rld::compress::compressor& comp); }; + /** + * Section detail + */ + struct section_detail + { + uint32_t name; //< The offset in the strtable. + uint32_t offset; //< The offset in the rap section. + uint32_t id; //< The rap id. + uint32_t obj; //< The obj id. + + /* Constructor */ + section_detail (const section_detail& s); + section_detail (); + }; + + section_detail::section_detail (const section_detail& s) + : name (s.name), + offset (s.offset), + id (s.id), + obj (s.obj) + { + } + + section_detail::section_detail () + : name (0), + offset (0), + id (0), + obj (0) + { + } + + /** + * A container of section_detail + */ + typedef std::list < section_detail > section_details; + /** * A RAP file. */ @@ -145,6 +194,13 @@ namespace rap off_t relocs_rap_off; uint32_t relocs_size; /* not used */ + off_t detail_rap_off; + uint32_t obj_num; + uint8_t** obj_name; + uint32_t* sec_num; + uint8_t* str_detail; + section_details sec_details; + section secs[rld::rap::rap_secs]; /** @@ -172,6 +228,11 @@ namespace rap */ void expand (); + /** + * Load details. + */ + void load_details(rld::compress::compressor& comp); + /** * The name. */ @@ -323,6 +384,11 @@ namespace rap symtab (0), relocs_rap_off (0), relocs_size (0), + detail_rap_off (0), + obj_num (0), + obj_name (0), + sec_num (0), + str_detail (0), warnings (warnings), image (name) { @@ -340,6 +406,13 @@ namespace rap delete [] symtab; if (strtab) delete [] strtab; + if (obj_name) + delete [] obj_name; + if (sec_num) + delete [] sec_num; + if (str_detail) + delete [] str_detail; + } void @@ -413,6 +486,44 @@ namespace rap image.seek (rhdr_len); } + void + file::load_details (rld::compress::compressor& comp) + { + uint32_t tmp; + + obj_name = new uint8_t*[obj_num]; + + sec_num = new uint32_t[obj_num]; + + /* how many sections of each object file */ + for (uint32_t i = 0; i < obj_num; i++) + { + comp >> tmp; + sec_num[i] = tmp; + } + + /* strtable size */ + comp >> tmp; + str_detail = new uint8_t[tmp]; + if (comp.read (str_detail, tmp) != tmp) + throw rld::error ("Reading file str details error", "rapper"); + + section_detail sec; + + for (uint32_t i = 0; i < obj_num; i++) + { + sec.obj = i; + for (uint32_t j = 0; j < sec_num[i]; j++) + { + comp >> sec.name; + comp >> tmp; + sec.offset = tmp & 0xfffffff; + sec.id = tmp >> 28; + + sec_details.push_back (section_detail (sec)); + } + } + } void file::load () { @@ -444,6 +555,16 @@ namespace rap >> strtab_size >> relocs_size; + /* + * Load the file details. + */ + detail_rap_off = comp.offset (); + + comp >> obj_num; + + if (obj_num > 0) + load_details(comp); + /* * uint32_t: text_size * uint32_t: text_alignment @@ -575,7 +696,8 @@ rap_show (rld::files::paths& raps, bool show_layout, bool show_strings, bool show_symbols, - bool show_relocs) + bool show_relocs, + bool show_details) { for (rld::files::paths::iterator pi = raps.begin(); pi != raps.end(); @@ -670,6 +792,49 @@ rap_show (rld::files::paths& raps, << " (" << r.relocs_rap_off << ')' << std::endl; } + if (show_details) + { + std::cout << " Details: 0x" + << std::hex << std::setfill ('0') + << std::setw (8) << r.detail_rap_off + << std::setfill (' ') << std::dec + << " (" << r.detail_rap_off << ')' << std::endl; + + if (r.obj_num == 0) + std::cout << " No details" << std::endl; + else + std::cout << ' ' << r.obj_num <<" Files" << std::endl; + + uint32_t pos = 0; + for (uint32_t i = 0; i < r.obj_num; ++i) + { + r.obj_name[i] = (uint8_t*) &r.str_detail[pos]; + pos += ::strlen ((char*) &r.str_detail[pos]) + 1; + } + + for (uint32_t i = 0; i < r.obj_num; ++i) + { + std::cout << " File: " << r.obj_name[i] << std::endl; + + for (rap::section_details::const_iterator sd = r.sec_details.begin (); + sd != r.sec_details.end (); + ++sd) + { + rap::section_detail tmp = *sd; + if (tmp.obj == i) + { + std::cout << std::setw (12) << "name:" + << std::setw (16) << (char*)&r.str_detail[tmp.name] + << " rap_section:"<< std::setw (8) + << rap::section_names[tmp.id] + << std::hex << " offset:0x" << tmp.offset << std::dec + << std::endl; + + } + } + } + } + if (show_strings) { std::cout << " Strings: 0x" @@ -766,7 +931,6 @@ rap_show (rld::files::paths& raps, } } } - } void @@ -911,7 +1075,8 @@ usage (int exit_code) << " -S : show symbols (also --symbols)" << std::endl << " -r : show relocations (also --relocs)" << std::endl << " -o : linkage overlay (also --overlay)" << std::endl - << " -x : expand (also --expand)" << std::endl; + << " -x : expand (also --expand)" << std::endl + << " -f : show file details" << std::endl; ::exit (exit_code); } @@ -967,12 +1132,13 @@ main (int argc, char* argv[]) bool show_strings = false; bool show_symbols = false; bool show_relocs = false; + bool show_details = false; bool overlay = false; bool expand = false; while (true) { - int opt = ::getopt_long (argc, argv, "hvVnaHlsSrox", rld_opts, NULL); + int opt = ::getopt_long (argc, argv, "hvVnaHlsSroxf", rld_opts, NULL); if (opt < 0) break; @@ -1000,6 +1166,7 @@ main (int argc, char* argv[]) show_strings = true; show_symbols = true; show_relocs = true; + show_details = true; break; case 'H': @@ -1040,6 +1207,10 @@ main (int argc, char* argv[]) expand = true; break; + case 'f': + show_details = true; + break; + case '?': case 'h': usage (0); @@ -1072,7 +1243,8 @@ main (int argc, char* argv[]) show_layout, show_strings, show_symbols, - show_relocs); + show_relocs, + show_details); if (overlay) rap_overlay (raps, warnings); -- cgit v1.2.3