static error_code getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I, char &Result) { const coff_symbol *symb = Obj.getCOFFSymbol(I); StringRef name; if (error_code ec = I->getName(name)) return ec; char ret = StringSwitch<char>(name) .StartsWith(".debug", 'N') .StartsWith(".sxdata", 'N') .Default('?'); if (ret != '?') { Result = ret; return object_error::success; } uint32_t Characteristics = 0; if (symb->SectionNumber > 0) { section_iterator SecI = Obj.end_sections(); if (error_code ec = I->getSection(SecI)) return ec; const coff_section *Section = Obj.getCOFFSection(SecI); Characteristics = Section->Characteristics; } switch (symb->SectionNumber) { case COFF::IMAGE_SYM_UNDEFINED: // Check storage classes. if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) { Result = 'w'; return object_error::success; // Don't do ::toupper. } else if (symb->Value != 0) // Check for common symbols. ret = 'c'; else ret = 'u'; break; case COFF::IMAGE_SYM_ABSOLUTE: ret = 'a'; break; case COFF::IMAGE_SYM_DEBUG: ret = 'n'; break; default: // Check section type. if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) ret = 't'; else if (Characteristics & COFF::IMAGE_SCN_MEM_READ && ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only. ret = 'r'; else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) ret = 'd'; else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) ret = 'b'; else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) ret = 'i'; // Check for section symbol. else if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC && symb->Value == 0) ret = 's'; } if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL) ret = ::toupper(static_cast<unsigned char>(ret)); Result = ret; return object_error::success; }