OpenASIP 2.2
Loading...
Searching...
No Matches
TPEFDumper.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2009 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24/**
25 * @file TPEFDumper.hh
26 *
27 * Definition of TPEFDumper class.
28 *
29 * @author Mikael Lepistö 2005 (tmlepist-no.spam-tut.fi)
30 * @note rating: red
31 */
32
33#include "TPEFDumper.hh"
34
35#include "BinaryReader.hh"
36#include "Binary.hh"
37#include "Section.hh"
38#include "UDataSection.hh"
39#include "DataSection.hh"
40#include "ASpaceSection.hh"
41#include "ASpaceElement.hh"
42#include "StringSection.hh"
43#include "SectionElement.hh"
44#include "SymbolElement.hh"
45#include "RelocElement.hh"
46#include "RelocSection.hh"
47#include "ResourceSection.hh"
48#include "ResourceElement.hh"
49#include "Chunk.hh"
50#include "CodeSection.hh"
51#include "InstructionElement.hh"
52#include "TPEFTools.hh"
53#include "FileSymElement.hh"
54#include "SectionSymElement.hh"
55#include "CodeSymElement.hh"
56#include "ProcedSymElement.hh"
57#include "DataSymElement.hh"
58#include "TPEFDisassembler.hh"
60#include "sstream"
61#include "DebugElement.hh"
62#include "DebugStabElem.hh"
63
65using TPEF::Binary;
66using TPEF::Section;
79using TPEF::Chunk;
82using TPEF::TPEFTools;
90
91
92/**
93 * Constructor.
94 */
95TPEFDumper::TPEFDumper(Binary& tpef, std::ostream& out) :
96 tpef_(tpef), out_(out), onlyLogicalInfo_(false) {
97}
98
99/**
100 * Destructor.
101 */
104
105/**
106 * Organizes sections alphabetically and creates index table.
107 *
108 * NOTE: method does not work if there is two sections
109 * with same header string (very rare).
110 */
111void
113
114 std::map<std::string, Word> organizedSections;
115
116 for (Word i = 0; i < tpef_.sectionCount(); i++) {
117 Section *sect = tpef_.section(i);
118 organizedSections[sectionHeader(*sect, true)] = i;
119 }
120
121 for (std::map<std::string, Word>::iterator
122 iter = organizedSections.begin();
123 iter != organizedSections.end();
124 iter++) {
125
126 actualIndexes_.push_back((*iter).second);
127 }
128}
129
130/**
131 * Converts index to print sections in logical order, if onlyLogical() is set.
132 *
133 * @param Requested index of section.
134 * @return Converted or same index that in parameter.
135 */
136Word
137TPEFDumper::actualIndex(Word origIndex) const {
138 if (onlyLogical()) {
139 return actualIndexes_[origIndex];
140 } else {
141 return origIndex;
142 }
143}
144
145/**
146 * Sets if dumper is wanted to print out only logical information of TPEF.
147 *
148 * If flag is set then no element or section indexes are dumped, only
149 * information that is independent to that how TPEF hierarchy is physically
150 * constructed is dumped. With this option user can check for example
151 * if two different TPEF files actually contains same program, relocations,
152 * symbols etc.
153 *
154 * @param flag If true, then logical printing is set on.
155 */
156void
158 if (flag) {
160 }
161
162 onlyLogicalInfo_ = flag;
163}
164
165/**
166 * Returns true if dumper is set to print only logical information.
167 *
168 * See. setOnlyLogical for more information.
169 *
170 * @return True if dumper is set to print only logical information.
171 */
172bool
174 return onlyLogicalInfo_;
175}
176
177/**
178 * Prints file headers.
179 */
180void
182
183 // generate string for strings() field of binary
184 int strSectionIndex = findSectionIndex(*tpef_.strings());
185 std::string strIndexString;
186
187 if (strSectionIndex != -1) {
188 strIndexString = Conversion::toString(strSectionIndex);
189 } else if (tpef_.strings() == NULL) {
190 strIndexString = "No strings section defined";
191 } else {
192 strIndexString = "INVALID TPEF: String section was not found.";
193 }
194
195 out_ << std::left
196 << std::setw(20) << "Section count: " << tpef_.sectionCount()
197 << std::endl
198 << std::setw(20) << "String section: " << sectionString(*tpef_.strings(), false)
199 << std::endl
200 << std::setw(20) << "File architecture: "
201 << fileArchString(tpef_.arch()) << std::endl
202 << std::setw(20) << "File type: " << fileTypeString(tpef_.type())
203 << std::endl << std::endl;
204}
205
206/**
207 * Prints one lined section header for every section.
208 */
209void
211
212 out_ << sectionHeader() << std::endl;
213
214 for (Word i = 0; i < tpef_.sectionCount(); i++) {
215 Section *sect = tpef_.section(actualIndex(i));
216
217 out_ << sectionHeader(*sect) << std::endl;
218 }
219
220 out_ << std::endl
221 << "B = Bytes. U = MAUs. E = SectionElements."
222 << std::endl;
223
224 out_ << std::endl;
225}
226
227/**
228 * Prints information about needed data address space sizes for
229 * initialized and uninitialized data.
230 */
231void
233
234 out_ << "Minimum sizes for address spaces:" << std::endl << std::endl;
235
236 // map of used address spaces
237 std::map<ASpaceElement*, std::pair<int, int> > neededMAUsOfASpace;
238 // map telling if CODE and/or DATA memory is used in this aspace
239 std::map<ASpaceElement*, std::pair<bool, bool> > typeOfMemNeeded;
240
241 for (Word i = 0; i < tpef_.sectionCount(); i++) {
242 Section& currSect = *tpef_.section(actualIndex(i));
243
244 if (currSect.isProgramSection()) {
245
246 // init new address space limits to 0,0
247 if (neededMAUsOfASpace.find(currSect.aSpace()) ==
248 neededMAUsOfASpace.end()) {
249
250 neededMAUsOfASpace[currSect.aSpace()] = std::pair<int,int>(0,0);
251 typeOfMemNeeded[currSect.aSpace()] = std::pair<bool,bool>(false,false);
252 }
253
254 std::pair<int,int> currentLimits = neededMAUsOfASpace[currSect.aSpace()];
255 int currMin = currSect.startingAddress();
256 int currMax = currMin;
257 std::pair<bool,bool> currentMemtypes = typeOfMemNeeded[currSect.aSpace()];
258
259 if (currSect.type() == Section::ST_CODE) {
260
261 currMax += dynamic_cast<const CodeSection*>
262 (&currSect)->instructionCount();
263 currentMemtypes.first = true;
264
265 } else if (currSect.type() == Section::ST_DATA ||
266 currSect.type() == Section::ST_UDATA ||
267 currSect.type() == Section::ST_LEDATA) {
268
269 currMax += dynamic_cast<const UDataSection*>(
270 &currSect)->lengthInMAUs();
271 currentMemtypes.second = true;
272
273 } else {
274 assert(false && "Unknown program section type");
275 }
276
277 // update limits to map
278 if (currMin < currentLimits.first) {
279 currentLimits.first = currMin;
280 }
281
282 if (currMax > currentLimits.second) {
283 currentLimits.second = currMax;
284 }
285
286 neededMAUsOfASpace[currSect.aSpace()] = currentLimits;
287 typeOfMemNeeded[currSect.aSpace()] = currentMemtypes;
288 }
289 }
290
291 // print out in ASpace order...
292 Section* aSpaces = tpef_.section(Section::ST_ADDRSP, 0);
293
294 for (Word i = 0; i < aSpaces->elementCount(); i++) {
295 ASpaceElement* aSpace =
296 dynamic_cast<ASpaceElement*>(aSpaces->element(i));
297
298 if (neededMAUsOfASpace.find(aSpace) != neededMAUsOfASpace.end()) {
299 int aSpaceSize =
300 neededMAUsOfASpace[aSpace].second -
301 neededMAUsOfASpace[aSpace].first;
302
303 out_ << i << ":";
304 if (typeOfMemNeeded[aSpace].first) out_ << " CODE";
305 if (typeOfMemNeeded[aSpace].second) out_ << " DATA";
306 out_ << ": " << aSpaceSize << " MAU(s)" << std::endl;
307
308 } else {
309 out_ << i << ": not used for data nor instructions."
310 << std::endl;
311 }
312 }
313
314 out_ << std::endl;
315}
316
317/**
318 * Prints full information of every relocation table in tpef.
319 */
320void
322
323 for (Word i = 0; i < tpef_.sectionCount(); i++) {
324 Section& currSect = *tpef_.section(actualIndex(i));
325
326 if (currSect.type() == Section::ST_RELOC) {
327 section(currSect);
328 }
329 }
330}
331
332/**
333 * Prints full information of every symbol table in tpef.
334 */
335void
337
338 for (Word i = 0; i < tpef_.sectionCount(); i++) {
339 Section& currSect = *tpef_.section(actualIndex(i));
340
341 if (currSect.type() == Section::ST_SYMTAB) {
342 section(currSect);
343 }
344 }
345}
346
347/**
348 * Prints full information of one section in tpef.
349 *
350 * @param sectionIndex Index of requested section.
351 */
352void
353TPEFDumper::section(Word sectionIndex) {
354 if (sectionIndex < tpef_.sectionCount()) {
355 section(*tpef_.section(actualIndex(sectionIndex)));
356
357 } else {
358 out_ << "There is no section with index: " << sectionIndex
359 << std::endl << std::endl;
360 }
361}
362
363/**
364 * Returns field names (first line of table) of section header table.
365 *
366 * @return field names (first line of table) of section header table.
367 */
368std::string
370 std::stringstream retVal;
371
372 retVal << std::setw(6) << std::left << "index"
373 << std::setw(15)<< std::right << "type"
374 << std::setw(12) << "address"
375 << std::setw(17) << "address space"
376 << std::setw(9) << "flags"
377 << std::setw(12) << "link"
378 << std::setw(15) << "size(B/U/E)"
379 << std::left << "\tname";
380
381 return retVal.str();
382}
383
384/**
385 * Returns section header string of one section.
386 *
387 * @param sect Section whose header is printed.
388 * @return section header information of one section.
389 */
390std::string
391TPEFDumper::sectionHeader(Section &sect, bool noIndex) {
392
393 std::string nameString;
394 if (tpef_.strings() == NULL) {
395 nameString = "No section name defined.";
396 } else {
397 nameString = tpef_.strings()->chunk2String(sect.name());
398 }
399
400 std::string elementsOrMAUs;
401 if (sect.isChunkable()) {
402
403 if (sect.type() == Section::ST_STRTAB) {
404 elementsOrMAUs = Conversion::toString(
405 dynamic_cast<UDataSection&>(sect).length()) + " B";
406 } else {
407 elementsOrMAUs = Conversion::toString(
408 dynamic_cast<UDataSection&>(sect).lengthInMAUs()) + " U";
409 }
410
411 } else {
412 elementsOrMAUs = Conversion::toString(sect.elementCount()) + " E";
413 }
414
415 int sectIndex = findSectionIndex(sect);
416
417 std::stringstream retVal;
418
419 retVal << std::left;
420 if (!noIndex) {
421 retVal << std::setw(6)
422 << Conversion::toString(sectIndex) + ":"
423 << std::setw(15) << std::right;
424 }
425
426 retVal << sectionTypeString(sect.type())
427 << std::setw(12) << sect.startingAddress()
428 << std::setw(17) << addressSpaceString(*sect.aSpace())
429 << std::setw(9) << Conversion::toHexString((int)sect.flags(),2)
430 << std::setw(12) << sectionString(*sect.link(), false)
431 << std::setw(15) << elementsOrMAUs
432 << std::left << "\t" + nameString;
433
434 return retVal.str();
435}
436
437/**
438 * Returns section index and/or type information.
439 *
440 * @param sect Section whose string is requested.
441 * @param shortForm If true then only index is returned.
442 * @return Type and/or index of section.
443 */
444std::string
445TPEFDumper::sectionString(Section &sect, bool shortForm) {
446 std::string str;
447
448 int index = findSectionIndex(sect);
449
450 if (index == -1) {
451 str = "FAIL";
452 } else {
453 if (!shortForm) {
454 str = sectionTypeString(sect.type(), true) + ":";
455 }
456 str += Conversion::toString(index);
457 }
458
459 return str;
460}
461
462/**
463 * Prints all information of requested section.
464 *
465 * @param sect Section to print.
466 */
467void
469
470 std::set<std::string> organizedElements;
471
472 switch (sect.type()) {
473 case Section::ST_SYMTAB: {
474 out_ << "Symbol table:" << std::endl << std::endl;
475 out_ << sectionHeader() << std::endl;;
476 out_ << sectionHeader(sect) << std::endl;
477
478 out_ << std::endl << std::left;
479
480 if (!onlyLogical()) {
481 out_ << std::setw(6) << "index" << std::right;
482 }
483
484 out_ << std::setw(17) << "type" << std::right
485 << std::setw(15) << "binding"
486 << std::setw(10) << "absolute"
487 << std::setw(12) << "owner"
488 << std::setw(15) << "value"
489 << std::left << "\tname"
490 << std::endl << std::endl;
491
492 StringSection* strings = dynamic_cast<StringSection*>(sect.link());
493
494 for (Word i = 0; i < sect.elementCount(); i++) {
495 SymbolElement* sym =
496 dynamic_cast<SymbolElement*>(sect.element(i));
497
498 std::string isAbso = (sym->absolute()) ? ("yes") : ("no");
499
500 // resolve value
501 std::string symValue;
502 switch (sym->type()) {
503 case SymbolElement::STT_NOTYPE: {
504 symValue = "NONE";
505 } break;
506
507 case SymbolElement::STT_SECTION: {
508 symValue = Conversion::toString(
509 dynamic_cast<SectionSymElement*>(sym)->value());
510 } break;
511
512 case SymbolElement::STT_FILE: {
513 symValue = Conversion::toString(
514 dynamic_cast<FileSymElement*>(sym)->value());
515 } break;
516
517 case SymbolElement::STT_DATA: {
518 UDataSection* uDataSect =
519 dynamic_cast<UDataSection*>(sym->section());
520 assert(uDataSect != NULL);
521
522 DataSymElement* dataSym =
523 dynamic_cast<DataSymElement*>(sym);
524 assert(dataSym != NULL);
525
526 symValue = Conversion::toString(
527 uDataSect->chunkToMAUIndex(dataSym->reference())) +
528 " U";
529
530 } break;
531
532 case SymbolElement::STT_CODE:
533 case SymbolElement::STT_PROCEDURE: {
534 CodeSection* codeSect =
535 dynamic_cast<CodeSection*>(sym->section());
536
537 assert(codeSect != NULL);
538
539 CodeSymElement* codeSym =
540 dynamic_cast<CodeSymElement*>(sym);
541 assert(codeSym != NULL);
542
543 symValue = Conversion::toString(
544 codeSect->indexOfElement(*codeSym->reference())) +
545 " E";
546 } break;
547
548
549 default:
550 symValue = "Unknown symbol type!";
551 };
552
553 std::stringstream elemStr;
554 elemStr << std::left;
555
556 if (!onlyLogical()) {
557 elemStr << std::setw(6)
558 << Conversion::toString(i) + ":"
559 << std::right;
560 }
561
562 elemStr << std::setw(17) << symbolTypeString(sym->type())
563 << std::right
564 << std::setw(15)
565 << symbolBindString(sym->binding())
566 << std::setw(10) << isAbso
567 << std::setw(12)
568 << sectionString(*sym->section(), false)
569 << std::setw(15) << symValue
570 << std::left
571 << "\t" + strings->chunk2String(sym->name());
572
573 if (onlyLogical()) {
574 organizedElements.insert(elemStr.str());
575 } else {
576 out_ << elemStr.str() << std::endl;
577 }
578
579 elemStr.clear();
580 }
581
582 dumpStringSet(organizedElements);
583
584 out_ << std::endl
585 << "U = Minimum allocateable unit index. "
586 << "E = Section element index. "
587 << std::endl;
588 } break;
589
590 case Section::ST_RELOC: {
591 RelocSection& relocSect =
592 dynamic_cast<RelocSection&>(sect);
593
594 out_ << "Relocation table: " << std::endl;
595 out_ << "Referenced section: "
596 << sectionString(*relocSect.referencedSection())
597 << std::endl << std::endl;
598
599 out_ << sectionHeader() << std::endl;
600 out_ << sectionHeader(sect) << std::endl;
601
602 out_ << std::endl << std::left;
603
604 if (!onlyLogical()) {
605 out_ << std::setw(6) << "index" << std::right;
606 }
607
608 out_ << std::setw(17) << "type"
609 << std::right
610 << std::setw(6) << "size"
611 << std::setw(18) << "location"
612 << std::setw(18) << "destination"
613 << std::setw(17) << "address space"
614 << std::left << "\tsymbol"
615 << std::endl << std::endl;
616
617 for (Word i = 0; i < sect.elementCount(); i++) {
618 RelocElement* reloc =
619 dynamic_cast<RelocElement*>(sect.element(i));
620
621
622 std::string locationAddress;
623
624 if (relocSect.referencedSection()->type() == Section::ST_DATA ||
625 relocSect.referencedSection()->type() == Section::ST_LEDATA) {
626 Chunk* srcChunk = dynamic_cast<Chunk*>(reloc->location());
627
628 DataSection* dataSect =
629 dynamic_cast<DataSection*>(relocSect.referencedSection());
630
631 assert(dataSect != NULL);
632
633 locationAddress = Conversion::toString(
634 dataSect->chunkToMAUIndex(srcChunk)) + " U";
635
636 } else if (relocSect.referencedSection()->type() ==
637 Section::ST_CODE) {
638
639 CodeSection* codeSect =
640 dynamic_cast<CodeSection*>(relocSect.referencedSection());
641
642 assert(codeSect != NULL);
643
644 locationAddress = Conversion::toString(
645 codeSect->indexOfElement(
646 *dynamic_cast<InstructionElement*>(
647 reloc->location()))) + " E";
648
649 } else {
650 abortWithError("Section containing relocated elements must"
651 " be DATA or CODE.");
652 }
653
654 std::string destinationAddress;
655 Word dstAddress = 0;
656
657 // if relocation is resolved
658 if (reloc->destination() != NULL) {
659
660 Section& dstSection =
661 TPEFTools::sectionOfElement(tpef_, *reloc->destination());
662
663 if (dstSection.type() == Section::ST_CODE) {
664 CodeSection& codeSect =
665 dynamic_cast<CodeSection&>(dstSection);
666
667 dstAddress = codeSect.indexOfInstruction(
668 *dynamic_cast<InstructionElement*>(reloc->destination()));
669
670 } else if (dstSection.type() == Section::ST_DATA ||
671 dstSection.type() == Section::ST_LEDATA ||
672 dstSection.type() == Section::ST_UDATA) {
673
674 UDataSection& uDataSect =
675 dynamic_cast<UDataSection&>(dstSection);
676
677 assert(uDataSect.belongsToSection(dynamic_cast<Chunk*>(reloc->destination())));
678
679 dstAddress = uDataSect.chunkToMAUIndex(
680 dynamic_cast<Chunk*>(reloc->destination()));
681
682 } else {
683 abortWithError("Destination of relocation must be DATA, "
684 "UDATA or CODE section.");
685 }
686
687 dstAddress += dstSection.startingAddress();
688 }
689
690 std::stringstream elemStr;
691 elemStr << std::left;
692
693 if (!onlyLogical()) {
694 elemStr << std::setw(6) << Conversion::toString(i) + ":"
695 << std::right;
696 }
697
698 elemStr << std::setw(17) << relocTypeString(reloc->type())
699 << std::right
700 << std::setw(6) << static_cast<Word>(reloc->size())
701 << std::setw(18) << locationAddress;
702
703 if (reloc->destination() != NULL) {
704 elemStr << std::setw(18)
705 << Conversion::toString(dstAddress) + " A";
706 } else {
707 elemStr << std::setw(18)
708 << "Unresolved";
709 }
710
711 elemStr << std::setw(17) << addressSpaceString(*reloc->aSpace())
712 << std::left
713 << "\t" + symbolString(*sect.link(), *reloc->symbol());
714
715 if (onlyLogical()) {
716 organizedElements.insert(elemStr.str());
717 } else {
718 out_ << elemStr.str() << std::endl;
719 }
720 }
721
722 dumpStringSet(organizedElements);
723
724 out_ << std::endl
725 << "E = Section element index. "
726 << "U = Minimum allocateable unit Index. "
727 << "A = Address of the address space."
728 << std::endl << std::endl;
729
730 } break;
731
732 case Section::ST_ADDRSP: {
733 out_ << "Address space table:"
734 << std::endl << std::endl;
735
736 out_ << sectionHeader() << std::endl;
737 out_ << sectionHeader(sect) << std::endl;
738
739
740 out_ << std::endl << std::left;
741 if (!onlyLogical()) {
742 out_ << std::setw(6) << "index" << std::right;
743 }
744
745 out_ << std::setw(6) << "MAU"
746 << std::right
747 << std::setw(10) << "alignment"
748 << std::setw(10) << "word size"
749 << std::left << "\tname"
750 << std::endl << std::endl;
751
752 StringSection* strings = dynamic_cast<StringSection*>(sect.link());
753
754 for (Word i = 0; i < sect.elementCount(); i++) {
755 ASpaceElement* aSpace =
756 dynamic_cast<ASpaceElement*>(sect.element(i));
757
758 std::stringstream elemStr;
759
760 elemStr << std::left;
761 if (!onlyLogical()) {
762 elemStr << std::setw(6) << Conversion::toString(i) + ":"
763 << std::right;
764 }
765
766 elemStr << std::setw(6) << static_cast<Word>(aSpace->MAU())
767 << std::right
768 << std::setw(10) << static_cast<Word>(aSpace->align())
769 << std::setw(10) << static_cast<Word>(aSpace->wordSize())
770 << std::left
771 << "\t" + strings->chunk2String(aSpace->name());
772
773 if (onlyLogical()) {
774 organizedElements.insert(elemStr.str());
775 } else {
776 out_ << elemStr.str() << std::endl;
777 }
778 }
779
780 dumpStringSet(organizedElements);
781
782
783 } break;
784
785 case Section::ST_MR: {
786 out_ << "Machine resource table:"
787 << std::endl << std::endl;
788
789 out_ << sectionHeader() << std::endl;
790 out_ << sectionHeader(sect) << std::endl;
791
792 if (onlyLogical()) {
793 out_ << std::endl << std::left
794 << std::setw(12) << "type"
795 << std::right
796 << std::setw(8) << "info"
797 << std::left << "\tname"
798 << std::endl << std::endl;
799 } else {
800 out_ << std::endl << std::left
801 << std::setw(6) << "index"
802 << std::setw(12) << std::right << "type"
803 << std::setw(17) << "id"
804 << std::setw(8) << "info"
805 << std::left << "\tname"
806 << std::endl << std::endl;
807 }
808
809 StringSection* strings = dynamic_cast<StringSection*>(sect.link());
810
811 for (Word i = 0; i < sect.elementCount(); i++) {
812 ResourceElement* res =
813 dynamic_cast<ResourceElement*>(sect.element(i));
814
815 std::stringstream elemStr;
816
817 if (onlyLogical()) {
818 elemStr << std::left
819 << std::setw(12)
820 << resourceTypeString(res->type())
821 << std::right
822 << std::setw(8) << res->info()
823 << std::left
824 << "\t" + strings->chunk2String(res->name());
825
826 organizedElements.insert(elemStr.str());
827
828 } else {
829 out_ << std::left
830 << std::setw(6) << Conversion::toString(i) + ":"
831 << std::setw(12) << std::right
832 << resourceTypeString(res->type())
833 << std::setw(17)
834 << resourceIdString(res->id(), res->type())
835 << std::setw(8) << res->info()
836 << std::left
837 << "\t" + strings->chunk2String(res->name())
838 << std::endl;
839 }
840 }
841
842 dumpStringSet(organizedElements);
843
844
845 } break;
846
847 case Section::ST_CODE: {
848 out_ << "Code section:"
849 << std::endl << std::endl;
850 out_ << sectionHeader() << std::endl;
851 out_ << sectionHeader(sect) << std::endl;
852
853 out_ << std::endl;
854
855 TPEFDisassembler disasm(tpef_);
856
857 for (Word i = 0; i < disasm.instructionCount(); i++) {
858
859 DisassemblyInstruction *instr = disasm.createInstruction(i);
860
861 out_ << std::left << std::setw(10)
863 i + disasm.startAddress()) + ":"
864 << std::left
865 << instr->toString()
866 << std::endl;
867
868 delete instr;
869 }
870
871 } break;
872
873 case Section::ST_DATA: {
874 out_ << "Data section:"
875 << std::endl << std::endl;
876
877 out_ << sectionHeader() << std::endl;
878 out_ << sectionHeader(sect) << std::endl;
879
880 DataSection &data = dynamic_cast<DataSection&>(sect);
881
882 for (Word i = 0; i < data.lengthInMAUs(); i++) {
883
884 if (i%16 == 0) {
885 out_ << std::endl << std::setw(9) <<
886 Conversion::toString(i + data.startingAddress()) + ":";
887 }
888
889 out_ << std::setw(sizeof(MinimumAddressableUnit)*2 + 3)
890 << Conversion::toHexString(data.MAU(i));
891
892 }
893
894 out_ << std::endl;
895 } break;
896
897 case Section::ST_LEDATA: {
898 out_ << "Low Endian Data section:"
899 << std::endl << std::endl;
900
901 out_ << sectionHeader() << std::endl;
902 out_ << sectionHeader(sect) << std::endl;
903
904 DataSection &data = dynamic_cast<DataSection&>(sect);
905
906 for (Word i = 0; i < data.lengthInMAUs(); i++) {
907
908 if (i%16 == 0) {
909 out_ << std::endl << std::setw(9) <<
910 Conversion::toString(i + data.startingAddress()) + ":";
911 }
912
913 out_ << std::setw(sizeof(MinimumAddressableUnit)*2 + 3)
914 << Conversion::toHexString(data.MAU(i));
915
916 }
917
918 out_ << std::endl;
919
920 } break;
921
922 case Section::ST_STRTAB: {
923 out_ << "String section:"
924 << std::endl << std::endl;
925
926 out_ << sectionHeader() << std::endl;
927 out_ << sectionHeader(sect) << std::endl;
928
929 out_ << std::endl << std::left;
930
931 if (!onlyLogical()) {
932 out_ << std::setw(10) << "offset";
933 }
934
935 out_ << std::left << "string "
936 << std::endl << std::endl;
937
938 StringSection &strings = dynamic_cast<StringSection&>(sect);
939
940 for (Word i = 0; i < strings.length(); i++) {
941 std::stringstream elemStr;
942
943 if (!onlyLogical()) {
944 elemStr << std::setw(10) << std::left
945 << Conversion::toString(i) + ":";
946 }
947
948 while (strings.byte(i) != 0) {
949 elemStr << strings.byte(i++);
950 }
951
952 if (onlyLogical()) {
953 organizedElements.insert(elemStr.str());
954 } else {
955 out_ << elemStr.str() << std::endl;
956 }
957 }
958
959 dumpStringSet(organizedElements);
960
961
962 } break;
963
964 case Section::ST_DEBUG: {
965 out_ << "Debug section:"
966 << std::endl << std::endl;
967
968 out_ << sectionHeader() << std::endl;
969 out_ << sectionHeader(sect) << std::endl;
970
971 out_ << std::endl << std::left;
972
973 out_ << std::setw(10) << "type";
974 out_ << std::left << "data "
975 << std::endl << std::endl;
976
977 for (Word i = 0; i < sect.elementCount(); i++) {
978
979 std::stringstream elemStr;
980
981 DebugElement* elem = dynamic_cast<DebugElement*>(sect.element(i));
982
983 elemStr << std::setw(10) << std::left
984 << debugElementTypeString(elem->type());
985
986 for (unsigned int j = 0; j < elem->length(); j++) {
987 elemStr << std::hex << std::setw(3)
988 << static_cast<int>(elem->byte(j));
989 }
990
991 elemStr << "\t"
992 << dynamic_cast<StringSection*>(
993 sect.link())->chunk2String(elem->debugString());
994
995 if (onlyLogical()) {
996 organizedElements.insert(elemStr.str());
997 } else {
998 out_ << elemStr.str() << std::endl;
999 }
1000 }
1001
1002 dumpStringSet(organizedElements);
1003
1004 } break;
1005
1006 default:
1007 out_ << "Printing section type: " << sectionTypeString(sect.type())
1008 << " is not implemented." << std::endl;
1009 }
1010
1011 out_ << std::endl;
1012}
1013
1014/**
1015 * Returns index of section.
1016 *
1017 * If section is not found from tpef returns -1.
1018 *
1019 * @param sect Section whose index is returned.
1020 * @return Index of section or error code.
1021 */
1022int
1024
1025 int index = 0;
1026 while (static_cast<Word>(index) < tpef_.sectionCount() &&
1027 tpef_.section(index) != &sect) {
1028
1029 index++;
1030 }
1031
1032 if (static_cast<Word>(index) < tpef_.sectionCount()) {
1033 for (Word i = 0; i < tpef_.sectionCount(); i++) {
1034 if (actualIndex(i) == static_cast<Word>(index)) {
1035 return i;
1036 }
1037 }
1038 }
1039
1040 return -1;
1041}
1042
1043/**
1044 * Returns index of element.
1045 *
1046 * If element is not found from section returns -1.
1047 *
1048 * @param sect Section which contains the element.
1049 * @param elem Element whose index is returned.
1050 * @return Index of element or error code.
1051 */
1052int
1054 int index = 0;
1055
1056 while (static_cast<Word>(index) < sect.elementCount() &&
1057 sect.element(index) != &elem) {
1058 index++;
1059 }
1060
1061 if (static_cast<Word>(index) < sect.elementCount()) {
1062 return index;
1063 } else {
1064 return -1;
1065 }
1066}
1067
1068/**
1069 * Returns section type in human readable form.
1070 *
1071 * @param type Type id to convert.
1072 * @param shortForm If short form (only enum string) is returned.
1073 * @return Section type id string.
1074 */
1075std::string
1077 Section::SectionType type, bool shortForm) {
1078
1079 std::string typeStr;
1080
1081 switch (type) {
1082 case Section::ST_NULL: typeStr = "NULL"; break;
1083 case Section::ST_STRTAB: typeStr = "STRTAB"; break;
1084 case Section::ST_SYMTAB: typeStr = "SYMTAB"; break;
1085 case Section::ST_DEBUG: typeStr = "DEBUG"; break;
1086 case Section::ST_RELOC: typeStr = "RELOC"; break;
1087 case Section::ST_LINENO: typeStr = "LINENO"; break;
1088 case Section::ST_NOTE: typeStr = "NOTE"; break;
1089 case Section::ST_ADDRSP: typeStr = "ADDRSP"; break;
1090 case Section::ST_MR: typeStr = "MR"; break;
1091 case Section::ST_CODE: typeStr = "CODE"; break;
1092 case Section::ST_DATA: typeStr = "DATA"; break;
1093 case Section::ST_UDATA: typeStr = "UDATA"; break;
1094 case Section::ST_LEDATA: typeStr = "LEDATA"; break;
1095 case Section::ST_DUMMY: typeStr = "DUMMY"; break;
1096 default: typeStr = "UNKNOWN";
1097 }
1098
1099 if (!shortForm) {
1100 typeStr += " (" + Conversion::toHexString(type, 2) + ")";
1101 }
1102
1103 return typeStr;
1104}
1105
1106/**
1107 * Returns file architecture type in human readable form.
1108 *
1109 * @param arch Architecture id to convert.
1110 * @return Architecture id string.
1111 */
1112std::string
1114
1115 std::string str;
1116
1117 switch (arch) {
1118 case Binary::FA_NOARCH: str = "NOARCH"; break;
1119 case Binary::FA_TTA_MOVE:str = "TTA_MOVE";break;
1120 case Binary::FA_TTA_TUT: str = "TTA_TUT"; break;
1121 case Binary::FA_TDS_TI: str = "TDS_TI"; break;
1122 default: str = "UNKNOWN";
1123 }
1124
1125 return str + " (" + Conversion::toHexString(arch, 2) + ")";
1126}
1127
1128/**
1129 * Returns debug element type string in human readable form.
1130 *
1131 * @param type Type id to convert.convert.
1132 * @return Type in string form.
1133 */
1134std::string
1136
1137 std::string str;
1138
1139 switch (type) {
1140 case DebugElement::DE_STAB: str = "STAB"; break;
1141 default: str = "UNKNOWN";
1142 }
1143
1144 return str;
1145}
1146
1147/**
1148 * Returns file type in human readable form.
1149 *
1150 * @param type File type id to convert.
1151 * @return File type id string.
1152 */
1153std::string
1155
1156 std::string str;
1157
1158 switch (type) {
1159 case Binary::FT_NULL: str = "UNDEF"; break;
1160 case Binary::FT_OBJSEQ: str = "OBJSEQ"; break;
1161 case Binary::FT_PURESEQ: str = "PURESEQ"; break;
1162 case Binary::FT_LIBSEQ: str = "LIBSEQ"; break;
1163 case Binary::FT_MIXED: str = "MIXED"; break;
1164 case Binary::FT_PARALLEL:str = "PARALLEL";break;
1165 default: str = "UNKNOWN";
1166 }
1167
1168 return str + " (" + Conversion::toHexString(type, 2) + ")";
1169}
1170
1171/**
1172 * Returns symbol type in human readable form.
1173 *
1174 * @param type Symbol type id to convert.
1175 * @return Symbol type id string.
1176 */
1177std::string
1179
1180 std::string str;
1181
1182 switch (type) {
1183 case SymbolElement::STT_NOTYPE: str = "NOTYPE"; break;
1184 case SymbolElement::STT_CODE: str = "CODE"; break;
1185 case SymbolElement::STT_DATA: str = "DATA"; break;
1186 case SymbolElement::STT_FILE: str = "FILE"; break;
1187 case SymbolElement::STT_SECTION: str = "SECTION"; break;
1188 case SymbolElement::STT_PROCEDURE: str = "PROCEDURE"; break;
1189 default: str = "UNKNOWN";
1190 }
1191
1192 return str + " (" + Conversion::toHexString(type, 2) + ")";
1193}
1194
1195/**
1196 * Returns symbol binding type in human readable form.
1197 *
1198 * @param bind Symbol binding type id to convert.
1199 * @return Symbol binding id string.
1200 */
1201std::string
1203
1204 std::string str;
1205
1206 switch (bind) {
1207 case SymbolElement::STB_LOCAL: str = "LOCAL"; break;
1208 case SymbolElement::STB_GLOBAL: str = "GLOBAL"; break;
1209 case SymbolElement::STB_WEAK: str = "WEAK"; break;
1210 default: str = "UNKNOWN";
1211 }
1212
1213 return str + " (" + Conversion::toHexString(bind, 2) + ")";
1214}
1215
1216/**
1217 * Returns srelocation type in human readable form.
1218 *
1219 * @param type Relocation type id to convert.
1220 * @return Relocation type id string.
1221 */
1222std::string
1224
1225 std::string str;
1226
1227 switch (type) {
1228 case RelocElement::RT_NOREL: str = "NOREL"; break;
1229 case RelocElement::RT_SELF: str = "SELF"; break;
1230 case RelocElement::RT_PAGE: str = "PAGE"; break;
1231 case RelocElement::RT_PCREL: str = "PCREL"; break;
1232 default: str = "UNKNOWN";
1233 }
1234
1235 return str + " (" + Conversion::toHexString(type, 2) + ")";
1236}
1237
1238/**
1239 * Returns resource type in human readable form.
1240 *
1241 * @param type Resource type id to convert.
1242 * @return Resource type id string.
1243 */
1244std::string
1246 std::string str;
1247 switch (type) {
1248 case ResourceElement::MRT_NULL:str = "NULL";break;
1249 case ResourceElement::MRT_BUS: str = "BUS"; break;
1250 case ResourceElement::MRT_UNIT:str = "UNIT";break;
1251 case ResourceElement::MRT_RF: str = "RF"; break;
1252 case ResourceElement::MRT_OP: str = "OP"; break;
1253 case ResourceElement::MRT_IMM: str = "IMM"; break;
1254 case ResourceElement::MRT_SR: str = "SR"; break;
1255 case ResourceElement::MRT_PORT:str = "PORT";break;
1256 default: str = "UNKNOWN";
1257 }
1258 return str + " (" + Conversion::toHexString(type, 2) + ")";
1259}
1260
1261/**
1262 * Returns resource id in human readable form.
1263 *
1264 * @param id Resource id to convert.
1265 * @param type Resource type of id. (needed for conversion)
1266 * @return Resource id string.
1267 */
1268std::string
1270 std::string str;
1271
1272 switch (type) {
1273
1274 case ResourceElement::MRT_UNIT:
1275 case ResourceElement::MRT_BUS: {
1276 if (id == 0) {
1277 str = "UNIVERSAL";
1278 }
1279 } break;
1280
1281 case ResourceElement::MRT_RF: {
1282 if (id == 0) {
1283 str = "ILLEGAL";
1284 } else if (id == ResourceElement::INT_RF) {
1285 str = "UNIV_INT";
1286 } else if (id == ResourceElement::BOOL_RF) {
1287 str = "UNIV_BOOL";
1288 } else if (id == ResourceElement::FP_RF) {
1289 str = "UNIV_FP";
1290 } else if ((id&ResourceElement::UNIVERSAL_RF_MASK) != 0) {
1291 str = "UNIV_UNKNWN";
1292 }
1293 } break;
1294
1295 case ResourceElement::MRT_IMM: {
1296 if (id == ResourceElement::INLINE_IMM) {
1297 str = "INLINE_IMM";
1298 }
1299
1300 } break;
1301
1302 default:
1303 return Conversion::toHexString(id, 4);
1304 }
1305
1306 if (str != "") {
1307 return str + " (" + Conversion::toHexString(id, 2) + ")";
1308 } else {
1309 return Conversion::toHexString(id, 4);
1310 }
1311}
1312
1313/**
1314 * Returns address space element in human readable form.
1315 *
1316 * @param aSpace Address space to convert.
1317 * @return Address space string.
1318 */
1319std::string
1321
1322 ASpaceSection* aSpaces = dynamic_cast<ASpaceSection*>(
1323 tpef_.section(Section::ST_ADDRSP,0));
1324
1325 assert(aSpaces != NULL);
1326
1327 StringSection* strings = dynamic_cast<StringSection*>(aSpaces->link());
1328 assert(strings != NULL);
1329
1330 std::string str;
1331 if (aSpaces->isUndefined(&aSpace)) {
1332 str = "undefined";
1333 } else {
1334 // find index
1335 int aSpaceIndex = findElementIndex(*aSpaces, aSpace);
1336
1337 assert(aSpaceIndex != -1);
1338
1339 if (!onlyLogical()) {
1340 str = Conversion::toString(aSpaceIndex) + ":";
1341 }
1342
1343 str +=
1344 Conversion::toString(static_cast<Word>(aSpace.MAU())) + "bit:" +
1345 Conversion::toString(static_cast<Word>(aSpace.align())) + ":" +
1346 Conversion::toString(static_cast<Word>(aSpace.wordSize()));
1347 }
1348
1349 return str;
1350}
1351
1352/**
1353 * Returns symbol in human readable form.
1354 *
1355 * @param sect Section containing requested symbol.
1356 * @param sym Symbol to convert.
1357 * @return Symbol string.
1358 */
1359std::string
1361
1362 std::string str;
1363 int index = findElementIndex(sect, sym);
1364
1365 StringSection* strings = dynamic_cast<StringSection*>(sect.link());
1366 assert(strings != NULL);
1367
1368 if (!onlyLogical()) {
1369 str = Conversion::toString(index) + ":";
1370 }
1371
1372 str += strings->chunk2String(sym.name());
1373
1374 return str;
1375}
1376
1377/**
1378 * Dumps a set of strings to output stream.
1379 *
1380 * Clears dumped set.
1381 *
1382 * @param set Set of strings to print.
1383 */
1384void
1385TPEFDumper::dumpStringSet(std::set<std::string> &aSet) const {
1386 typedef std::set<std::string>::iterator StrSetIter;
1387 for (StrSetIter iter = aSet.begin(); iter != aSet.end(); iter++) {
1388 out_ << *iter << std::endl;
1389 }
1390 aSet.clear();
1391}
#define abortWithError(message)
#define assert(condition)
Word MinimumAddressableUnit
Type for storing a MAU (must be unsigned type!). This limits the maximum size of the simulated minimu...
Definition BaseType.hh:184
find Finds info of the inner loops in the false
static std::string toHexString(T source, std::size_t digits=0, bool include0x=true)
static std::string toString(const T &source)
virtual Word startAddress() const
virtual DisassemblyInstruction * createInstruction(Word instructionIndex) const
virtual Word instructionCount() const
void section(Word sectionIndex)
TPEFDumper(TPEF::Binary &tpef, std::ostream &out)
Definition TPEFDumper.cc:95
void createLogicalIndexes()
virtual ~TPEFDumper()
std::string sectionString(TPEF::Section &sect, bool shortForm=false)
void fileHeaders()
std::vector< Word > actualIndexes_
std::string resourceIdString(HalfWord id, TPEF::ResourceElement::ResourceType type)
std::string debugElementTypeString(TPEF::DebugElement::ElementType type)
std::string addressSpaceString(TPEF::ASpaceElement &aSpace)
std::string symbolString(TPEF::Section &sect, TPEF::SymbolElement &sym)
std::string fileTypeString(TPEF::Binary::FileType type)
void sectionHeaders()
int findElementIndex(TPEF::Section &sect, TPEF::SectionElement &elem)
std::string symbolTypeString(TPEF::SymbolElement::SymbolType type)
void symbolTables()
std::string resourceTypeString(TPEF::ResourceElement::ResourceType type)
std::string relocTypeString(TPEF::RelocElement::RelocType type)
std::string sectionHeader()
bool onlyLogicalInfo_
void setOnlyLogical(bool flag)
int findSectionIndex(TPEF::Section &sect)
TPEF::Binary & tpef_
std::string sectionTypeString(TPEF::Section::SectionType type, bool shortForm=false)
bool onlyLogical() const
void relocationTables()
Word actualIndex(Word logicalIndex) const
std::ostream & out_
void dumpStringSet(std::set< std::string > &aSet) const
std::string fileArchString(TPEF::Binary::FileArchitecture arch)
void memoryInfo()
std::string symbolBindString(TPEF::SymbolElement::SymbolBinding bind)
Byte wordSize() const
Chunk * name() const
Byte align() const
Byte MAU() const
bool isUndefined(ASpaceElement *aSpace) const
Word sectionCount() const
Section * section(Word index) const
StringSection * strings() const
FileArchitecture arch() const
FileType type() const
Word indexOfInstruction(const InstructionElement &elem) const
Word indexOfElement(const InstructionElement &elem) const
InstructionElement * reference() const
virtual Word length() const
virtual Byte byte(const Chunk *chunk) const
virtual MinimumAddressableUnit MAU(Word index) const
Chunk * reference() const
virtual ElementType type() const =0
Chunk * debugString() const
virtual Word length() const =0
Returns the length of additional data of debug element.
virtual Byte byte(Word index) const =0
Returns one byte of additional data.
virtual Word chunkToMAUIndex(const Chunk *chunk) const
Definition Section.cc:341
virtual Word lengthInMAUs() const
Definition Section.cc:285
bool belongsToSection(const Chunk *chunk) const
Definition Section.cc:238
SectionElement * destination() const
ASpaceElement * aSpace() const
RelocType type() const
SymbolElement * symbol() const
SectionElement * location() const
Byte size() const
Section * referencedSection() const
ResourceType type() const
HalfWord id() const
ResourceType
Resource types.
Chunk * name() const
Chunk * name() const
AddressImage startingAddress() const
bool isProgramSection() const
Byte flags() const
Section * link() const
SectionElement * element(Word index) const
Word elementCount() const
virtual bool isChunkable() const
Definition Section.cc:157
virtual SectionType type() const =0
Returns SectioType of actual section instance.
ASpaceElement * aSpace() const
std::string chunk2String(const Chunk *chunk) const
SymbolType
Type of symbol element.
virtual SymbolType type() const =0
Returns type of symbol.
bool absolute() const
Section * section() const
SymbolBinding binding() const
Chunk * name() const
SymbolBinding
Binding types of symbol.