Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /****************************   error.cpp   **********************************
  2. * Author:        Agner Fog
  3. * Date created:  2006-07-15
  4. * Last modified: 2017-10-18
  5. * Project:       objconv
  6. * Module:        error.cpp
  7. * Description:
  8. * Standard procedure for error reporting to stderr
  9. *
  10. * Copyright 2006-2017 GNU General Public License http://www.gnu.org/licenses
  11. *****************************************************************************/
  12.  
  13. // Define this if you get problems:
  14. // #define OBJCONV_ERROR_CPP 1
  15.  
  16.  
  17. #include "stdafx.h"
  18.  
  19. #define MAX_ERROR_TEXT_LENGTH 1024 // Maximum length of error text including extra info
  20.  
  21.  
  22. // Make and initialize error reporter object
  23. CErrorReporter err;
  24.  
  25. SErrorText ErrorTexts[] = {
  26.    // Unknown error
  27.    {0,    2, "Unknown error number!"},
  28.  
  29.    // Warning messages
  30.    {1001, 1, "Empty command line option"},
  31.    {1002, 1, "Unknown command line option: %s"},
  32.    {1003, 1, "Unknown warning/error number: %i"},
  33.    {1006, 1, "Nothing do do. Copying file unchanged"},
  34.    {1008, 1, "Converting COFF file to ELF and back again."},
  35.    {1009, 1, "Converting OMF file to COFF and back again."},
  36.    {1010, 1, "Section index and section-relative fixup not supported in ELF file. Probably a debug record"},
  37.    {1011, 1, "Converting Mach-O file to ELF and back again."},
  38.    {1020, 1, "Non-public symbol %s cannot be made weak"},
  39.    {1021, 1, "Non-public symbol %s cannot be made local"},
  40.    {1022, 1, "Non-public symbol %s cannot get an alias"},
  41.    {1023, 1, "External symbol %s made local. Access to this symbol will cause error"},
  42.    {1024, 1, "Cannot change prefix on name %s, not a symbol"},
  43.    {1029, 1, "Debug information may be incompatible"},
  44.    {1030, 1, "Exception information may be incompatible"},
  45.    {1031, 1, "Windows resource information not translated"},  
  46.    {1032, 1, "More than one symbol table found in ELF file"},
  47.    {1033, 1, "Sorry, cannot currently make alias in dynamic symbol table. Symbol = %s"},
  48.    {1040, 1, "Name of section %s too long. Truncating to 16 characters"},
  49.    {1050, 0, "Position dependent references will not work in .so file. (First occurrence is symbol %s. This message can be turned off with -wd1050)"},
  50.    {1051, 1, "Weak public not supported in target file type, symbol %s"},
  51.    {1052, 1, "Indirect symbol index out of range"},
  52.    {1053, 1, "Common constant converted to public: %s"},
  53.    {1054, 1, "Cannot find import table"},
  54.    {1055, 1, "Communal section currently not supported by objconv. Section dropped"},
  55.    {1060, 1, "Different alignments specified for same segment, %s. Using highest alignment"},
  56.    {1061, 1, "Symbol %s has lazy binding"},
  57.    {1062, 1, "Symbol %s has unknown type"},
  58.    {1063, 1, "Gnu indirect function (CPU dispatcher) cannot be converted"},
  59.    {1101, 1, "Output file name should have extension .lib or .a"},
  60.    {1102, 1, "Library members have different type"},
  61.    {1103, 1, "Output file name ignored"},
  62.    {1104, 1, "Library member %s not found. Extraction failed"},
  63.    {1105, 1, "Library member %s not found. Deletion failed"},
  64.    {1106, 1, "Symbol %s not found. Modification of this symbol failed"},
  65.    {1107, 1, "Name of library member %s should have extension .o or .obj"},
  66.    {1108, 1, "Name of library member %s too long. Truncating to 15 characters"},
  67.    {1109, 1, "Library member %s has unknown type. Possibly alias record without code"},
  68.    {1150, 1, "Universal binary contains more than one component that can be converted. Specify desired word size or use lipo to extract desired component"},
  69.    {1151, 1, "Skipping component with wordsize %i"},
  70.  
  71.    {1202, 1, "OMF Record checksum error"},
  72.    {1203, 1, "Unrecognized data in OMF subrecord"},
  73.    {1204, 1, "String too long building OMF file. Truncating to 255 characters: %s"},
  74.    {1205, 1, "Alignment by %i possibly not supported for OMF file. Using page alignment (256 or 4096 depending on system)"},
  75.    {1206, 1, "Stack segment ignored"},
  76.    {1207, 1, "Overlapping data"},
  77.    {1208, 1, "Back-patched code (possibly OK)"},
  78.    {1211, 1, "%i comment records ignored"},
  79.    {1212, 1, "Record type (%s) not supported"},
  80.    {1213, 1, "Hash table has %i occurrences of name %s"},
  81.    {1214, 1, "Symbol %s defined in both modules %s"},
  82.    {1215, 1, "More than 251 blocks required in symbol hash table. May fail with some linkers"},
  83.    {1300, 1, "File contains 32-bit absolute address. Must link with option -image_base %s -pagezero_size 1000"},
  84.    {1301, 1, "Image-relative address converted to absolute. Assumes image base = "},
  85.    {1302, 1, "64-bit relocation with arbitrary reference point converted to 32-bit self-relative. Will fail if offset is negative"},
  86.    {1303, 1, "Cannot find imported symbol"},
  87.    {1304, 1, "Unknown relocation address"},
  88.  
  89.    // Error messages
  90.    {2001, 2, "No more than one input file and one output file can be specified"},
  91.    {2002, 2, "Word size (%i) not supported for output file"},
  92.    {2003, 2, "Only one output format option can be specified. Command line error at %s"},
  93.    {2004, 2, "Unknown command line option: %s"},
  94.    {2005, 2, "Input file and output file cannot have same name: %s"},
  95.    {2006, 2, "Unsupported file type for file %s: %s"},
  96.    {2007, 2, "Cannot dump and convert file in the same command"},
  97.    {2008, 2, "This option must have two symbol names: %s"},
  98.    {2009, 2, "This option must have one symbol name: %s"},
  99.    {2010, 2, "Sorry. Dump of file type %s is not supported"},
  100.    {2011, 2, "Sorry. Conversion of file type %s is not supported"},
  101.    {2012, 2, "Cannot convert from word size %i to word size %i"},
  102.    {2013, 2, "Sorry. Conversion of file type %s to %s is not supported"},
  103.    {2014, 2, "File contains information for .NET common language runtime. Cannot convert"},
  104.    {2015, 2, "More than one option specified for symbol %s"},
  105.    {2016, 2, "Index out of range"},
  106.    {2017, 2, "File name %s specified more than once"},
  107.    {2018, 2, "Unknown type 0x%X for file: %s"},
  108.    {2020, 2, "Overflow when converting value of symbol %s to 32 bits"},
  109.    {2021, 2, "File contains information for objective-C runtime code. Cannot convert"},
  110.    {2022, 2, "Cannot convert executable file"},
  111.  
  112.    {2030, 2, "Unsupported relocation type (%i)"},
  113.    {2031, 2, "Relocated symbol not found"},
  114.    {2032, 2, "Relocation points outside segment"},
  115.    {2033, 2, "Error in ELF file. Record size not specified"},
  116.    {2034, 2, "Symbol table not found in ELF file"},
  117.    {2035, 2, "Pointer out of range in object file"},
  118.    {2036, 2, "Unknown section index in ELF file: %i"},
  119.    {2037, 2, "Symbol storage/binding type %i not supported"},
  120.    {2038, 2, "Symbol type %i not supported"},
  121.    {2040, 2, "Symbol table corrupt in object file"},
  122.    {2041, 2, "File has relocation of uninitialized data"},
  123.    {2042, 2, "Relocation to global offset table found. Cannot convert position-independent code"},
  124.    {2043, 2, "Relocation to procedure linkage table found. Cannot convert"},
  125.    {2044, 2, "Relocation relative to arbitrary reference point that cannot be converted"},
  126.    {2045, 2, "Unknown import table type"},
  127.    {2050, 2, "Inconsistent relocation record pair"},
  128.    {2051, 2, "Too many symbols for Mach-O file. Maximum = 16M"},
  129.    {2052, 2, "Unexpected data between symbol table and string table"},
  130.  
  131.    {2103, 2, "Cannot read input file %s"},
  132.    {2104, 2, "Cannot write output file %s"},
  133.    {2105, 2, "Wrong size of file %s"},
  134.    {2107, 2, "Too many response files"},
  135.    {2110, 2, "COFF file section table corrupt"},
  136.    {2112, 2, "String table corrupt"},
  137.    {2114, 2, "This is an intermediate file for whole-program-optimization in Intel compiler"},
  138.    {2200, 2, "Weak public symbols not supported in this file format"},
  139.    {2202, 2, "Symbol name %s too long. Cannot change prefix"},
  140.    {2203, 2, "File name %s too long"},
  141.    {2210, 2, "File contains overlapping relocation sources"},
  142.    {2301, 2, "OMF Record extends beyond end of file"},
  143.    {2302, 2, "Fixup source extends beyond end of section"},
  144.    {2303, 2, "Too many symbols for OMF file. Index exceeds 32767"},
  145.    {2304, 2, "Word-size index exceeds 65535"},
  146.    {2305, 2, "%i Communal sections found. Currently not supported by Objconv"},
  147.    {2306, 2, "Segment size is 4 Gbytes"},
  148.    {2307, 2, "Segment address is absolute"},
  149.    {2308, 2, "Unknown alignment %i"},
  150.    {2309, 2, "Data outside bounds of segment %s"},
  151.    {2310, 2, "Iterated data outside bounds of segment"},
  152.    {2311, 2, "Relocation of iterated data not supported by objconv"},
  153.    {2312, 2, "FIXUPP record does not refer to data record"},
  154.    {2313, 2, "OMF file has compression of repeated relocation target (thread). This is not supported in objconv"},
  155.    {2314, 2, "Unknown relocation method T%i"},
  156.    {2315, 2, "Group-relative relocation to %s not supported"},
  157.    {2316, 2, "Incompatible relocation method: %s"},
  158.    {2317, 2, "Incompatible word size: %i"},
  159.    {2318, 2, "OMF file has compression of repeated communal data. This is not supported in objconv"},
  160.    {2320, 2, "Mixed 32-bit and 64-bit segments"},
  161.    {2321, 2, "Wrong record size found"},
  162.    {2330, 2, "Imagebase specified more than once"},
  163.    {2331, 2, "Imagebase must be divisible by page size 1000 (hexadecimal)"},
  164.    {2332, 2, "Imagebase must > 0 and < 80000000 (hexadecimal)"},
  165.  
  166.    {2500, 2, "Library/archive file is corrupt"},
  167.    {2501, 2, "Cannot store file of type %s in library"},
  168.    {2502, 2, "Too many members in library"},
  169.    {2503, 2, "Output file name must be specified"},
  170.    {2504, 2, "Object file type (%s) does not match library"},
  171.    {2505, 2, "Object file word size (%i) does not match library"},
  172.    {2506, 2, "Overflow of buffer for library member names"},
  173.    {2507, 2, "%s is an import library. Cannot convert to static library"},
  174.    {2600, 2, "Library has more than one header"},
  175.    {2601, 2, "Library page size (%i) is not a power of 2"},
  176.    {2602, 2, "Library end record does not match dictionary offset in OMF library"},
  177.    {2603, 2, "Public name %s not found in hash table"},
  178.    {2605, 2, "Symbol hash table too big. Creation of library failed"},
  179.    {2606, 2, "Too many library members. Creation of library failed"},
  180.    {2610, 2, "Library end record not found"},
  181.    {2620, 2, "You need to extract library members before disassembling"},
  182.    {2621, 2, "Wrong output file type"},
  183.  
  184.    {2701, 2, "Wrong number of members in universal binary (%i)"},
  185.  
  186.    {3000, 1, "Internal error in opcode table"},
  187.    {3001, 1, "Internal error: Unknown register type 0x%X"},
  188.  
  189.    // Fatal errors makes the program stop immediately:
  190.    {9000, 9, "Objconv program internal inconsistency"},
  191.    {9001, 9, "Objconv program has been compiled with wrong integer sizes"},
  192.    {9002, 9, "Objconv cannot run on machine with big-endian memory organization"},
  193.    {9003, 9, "Array index out of range"},
  194.    {9004, 9, "Cannot resize array of type CArrayBuf"},
  195.    {9005, 9, "Exceeding 1kb size limit while building OMF record"},
  196.    {9006, 9, "Memory allocation failed"},
  197.    {9007, 9, "Objcopy internal error in opcode map 0x%X"},
  198.  
  199.    // Mark end of list
  200.    {9999, 9999, "End of error text list"}
  201. };
  202.  
  203.  
  204. // Constructor for CErrorReporter
  205. CErrorReporter::CErrorReporter() {
  206.    NumErrors = NumWarnings = WorstError = 0;
  207.    MaxWarnings = 50;      // Max number of warning messages to pring
  208.    MaxErrors   = 50;      // Max number of error messages to print
  209. }
  210.  
  211. SErrorText * CErrorReporter::FindError(int ErrorNumber) {
  212.    // Search for error in ErrorTexts
  213.    int e;
  214.    const int ErrorTextsLength = sizeof(ErrorTexts) / sizeof(ErrorTexts[0]);
  215.    for (e = 0; e < ErrorTextsLength; e++) {
  216.       if (ErrorTexts[e].ErrorNumber == ErrorNumber) return ErrorTexts + e;
  217.    }
  218.    // Error number not found
  219.    static SErrorText UnknownErr = ErrorTexts[0];
  220.    UnknownErr.ErrorNumber = ErrorNumber;
  221.    UnknownErr.Status      = 0x102;  // Unknown error
  222.    return &UnknownErr;
  223. }
  224.  
  225.  
  226. void CErrorReporter::submit(int ErrorNumber) {
  227.    // Print error message with no extra info
  228.    SErrorText * err = FindError(ErrorNumber);
  229.    HandleError(err, err->Text);
  230. }
  231.  
  232. void CErrorReporter::submit(int ErrorNumber, int extra) {
  233.    // Print error message with extra numeric info
  234.    // ErrorTexts[ErrorNumber] must contain %i where extra is to be inserted
  235.    char text[MAX_ERROR_TEXT_LENGTH];
  236.    SErrorText * err = FindError(ErrorNumber);
  237.    snprintf(text, MAX_ERROR_TEXT_LENGTH, err->Text, extra);
  238.    HandleError(err, text);
  239. }
  240.  
  241. void CErrorReporter::submit(int ErrorNumber, int extra1, int extra2) {
  242.    // Print error message with 2 extra numeric values inserted
  243.    // ErrorTexts[ErrorNumber] must contain two %i fields where extra numbers are to be inserted
  244.    char text[MAX_ERROR_TEXT_LENGTH];
  245.    SErrorText * err = FindError(ErrorNumber);
  246.    snprintf(text, MAX_ERROR_TEXT_LENGTH, err->Text, extra1, extra2);
  247.    HandleError(err, text);
  248. }
  249.  
  250. void CErrorReporter::submit(int ErrorNumber, char const * extra) {
  251.    // Print error message with extra text info
  252.    // ErrorTexts[ErrorNumber] must contain %s where extra is to be inserted
  253.    char text[MAX_ERROR_TEXT_LENGTH];
  254.    SErrorText * err = FindError(ErrorNumber);
  255.    snprintf(text, MAX_ERROR_TEXT_LENGTH, err->Text, extra);
  256.    HandleError(err, text);
  257. }
  258.  
  259. void CErrorReporter::submit(int ErrorNumber, char const * extra1, char const * extra2) {
  260.    // Print error message with two extra text info fields
  261.    // ErrorTexts[ErrorNumber] must contain %s where extra texts are to be inserted
  262.    char text[MAX_ERROR_TEXT_LENGTH];
  263.    if (extra1 == 0) extra1 = "???"; if (extra2 == 0) extra2 = "???";
  264.    SErrorText * err = FindError(ErrorNumber);
  265.    snprintf(text, MAX_ERROR_TEXT_LENGTH, err->Text, extra1, extra2);
  266.    HandleError(err, text);
  267. }
  268.  
  269. void CErrorReporter::submit(int ErrorNumber, int extra1, char const * extra2) {
  270.    // Print error message with two extra text fields inserted
  271.    // ErrorTexts[ErrorNumber] must contain %i and %s where extra texts are to be inserted
  272.    char text[MAX_ERROR_TEXT_LENGTH];
  273.    if (extra2 == 0) extra2 = "???";
  274.    SErrorText * err = FindError(ErrorNumber);
  275.    snprintf(text, MAX_ERROR_TEXT_LENGTH, err->Text, extra1, extra2);
  276.    HandleError(err, text);
  277. }
  278.  
  279. void CErrorReporter::HandleError(SErrorText * err, char const * text) {
  280.    // HandleError is used by submit functions
  281.    // check severity
  282.    int severity = err->Status & 0x0F;
  283.    if (severity == 0) {
  284.       return;  // Ignore message
  285.    }
  286.    if (severity > 1 && err->ErrorNumber > WorstError) {
  287.       // Store highest error number
  288.       WorstError = err->ErrorNumber;
  289.    }
  290.    if (severity == 1) {
  291.       // Treat message as warning
  292.       if (++NumWarnings > MaxWarnings) return; // Maximum number of warnings has been printed
  293.       // Treat message as warning
  294.       fprintf(stderr, "\nWarning %i: %s", err->ErrorNumber, text);
  295.       if (NumWarnings == MaxWarnings) {
  296.          // Maximum number reached
  297.          fprintf(stderr, "\nSupressing further warning messages");
  298.       }
  299.    }
  300.    else {
  301.       // Treat message as error
  302.       if (++NumErrors > MaxErrors) return; // Maximum number of warnings has been printed
  303.       fprintf(stderr, "\nError %i: %s", err->ErrorNumber, text);
  304.       if (NumErrors == MaxErrors) {
  305.          // Maximum number reached
  306.          fprintf(stderr, "\nSupressing further warning messages");
  307.       }
  308.    }
  309.    if (severity == 9) {
  310.       // Abortion required
  311.       fprintf(stderr, "\nAborting\n");
  312.       exit(err->ErrorNumber);
  313.    }
  314. }
  315.  
  316. int CErrorReporter::Number() {
  317.    // Get number of fatal errors
  318.    return NumErrors;
  319. }
  320.  
  321. int CErrorReporter::GetWorstError() {
  322.    // Get highest warning or error number encountered
  323.    return WorstError;
  324. }
  325.  
  326. void CErrorReporter::ClearError(int ErrorNumber) {
  327.    // Ignore further occurrences of this error
  328.    int e;
  329.    const int ErrorTextsLength = sizeof(ErrorTexts) / sizeof(ErrorTexts[0]);
  330.    for (e = 0; e < ErrorTextsLength; e++) {
  331.       if (ErrorTexts[e].ErrorNumber == ErrorNumber) break;
  332.    }
  333.    if (e < ErrorTextsLength) {
  334.       ErrorTexts[e].Status = 0;
  335.    }
  336. }
  337.