Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
llvm/tools/llvm-nm/llvm-nm.cpp
Show All 22 Lines | |||||
#include "llvm/Object/Archive.h" | #include "llvm/Object/Archive.h" | ||||
#include "llvm/Object/COFF.h" | #include "llvm/Object/COFF.h" | ||||
#include "llvm/Object/COFFImportFile.h" | #include "llvm/Object/COFFImportFile.h" | ||||
#include "llvm/Object/ELFObjectFile.h" | #include "llvm/Object/ELFObjectFile.h" | ||||
#include "llvm/Object/IRObjectFile.h" | #include "llvm/Object/IRObjectFile.h" | ||||
#include "llvm/Object/MachO.h" | #include "llvm/Object/MachO.h" | ||||
#include "llvm/Object/MachOUniversal.h" | #include "llvm/Object/MachOUniversal.h" | ||||
#include "llvm/Object/ObjectFile.h" | #include "llvm/Object/ObjectFile.h" | ||||
#include "llvm/Object/TapiFile.h" | |||||
#include "llvm/Object/TapiUniversal.h" | |||||
#include "llvm/Object/Wasm.h" | #include "llvm/Object/Wasm.h" | ||||
#include "llvm/Support/CommandLine.h" | #include "llvm/Support/CommandLine.h" | ||||
#include "llvm/Support/FileSystem.h" | #include "llvm/Support/FileSystem.h" | ||||
#include "llvm/Support/Format.h" | #include "llvm/Support/Format.h" | ||||
#include "llvm/Support/InitLLVM.h" | #include "llvm/Support/InitLLVM.h" | ||||
#include "llvm/Support/MemoryBuffer.h" | #include "llvm/Support/MemoryBuffer.h" | ||||
#include "llvm/Support/Program.h" | #include "llvm/Support/Program.h" | ||||
#include "llvm/Support/Signals.h" | #include "llvm/Support/Signals.h" | ||||
▲ Show 20 Lines • Show All 166 Lines • ▼ Show 20 Lines | cl::opt<bool> DyldInfoOnly("dyldinfo-only", | ||||
cl::desc("Show only symbols from the dyldinfo, " | cl::desc("Show only symbols from the dyldinfo, " | ||||
"Mach-O only"), | "Mach-O only"), | ||||
cl::cat(NMCat)); | cl::cat(NMCat)); | ||||
cl::opt<bool> NoLLVMBitcode("no-llvm-bc", | cl::opt<bool> NoLLVMBitcode("no-llvm-bc", | ||||
cl::desc("Disable LLVM bitcode reader"), | cl::desc("Disable LLVM bitcode reader"), | ||||
cl::cat(NMCat)); | cl::cat(NMCat)); | ||||
cl::opt<bool> AddInlinedInfo("add-inlinedinfo", | |||||
cl::desc("Add symbols from the inlined libraries, " | |||||
"TBD(Mach-O) only"), | |||||
cl::cat(NMCat)); | |||||
cl::extrahelp HelpResponse("\nPass @FILE as argument to read options from FILE.\n"); | cl::extrahelp HelpResponse("\nPass @FILE as argument to read options from FILE.\n"); | ||||
bool PrintAddress = true; | bool PrintAddress = true; | ||||
bool MultipleFiles = false; | bool MultipleFiles = false; | ||||
bool HadError = false; | bool HadError = false; | ||||
▲ Show 20 Lines • Show All 114 Lines • ▼ Show 20 Lines | |||||
static char isSymbolList64Bit(SymbolicFile &Obj) { | static char isSymbolList64Bit(SymbolicFile &Obj) { | ||||
if (auto *IRObj = dyn_cast<IRObjectFile>(&Obj)) | if (auto *IRObj = dyn_cast<IRObjectFile>(&Obj)) | ||||
return Triple(IRObj->getTargetTriple()).isArch64Bit(); | return Triple(IRObj->getTargetTriple()).isArch64Bit(); | ||||
if (isa<COFFObjectFile>(Obj) || isa<COFFImportFile>(Obj)) | if (isa<COFFObjectFile>(Obj) || isa<COFFImportFile>(Obj)) | ||||
return false; | return false; | ||||
if (isa<WasmObjectFile>(Obj)) | if (isa<WasmObjectFile>(Obj)) | ||||
return false; | return false; | ||||
if (TapiFile *Tapi = dyn_cast<TapiFile>(&Obj)) | |||||
return Tapi->is64Bit(); | |||||
if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj)) | if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj)) | ||||
return MachO->is64Bit(); | return MachO->is64Bit(); | ||||
return cast<ELFObjectFileBase>(Obj).getBytesInAddress() == 8; | return cast<ELFObjectFileBase>(Obj).getBytesInAddress() == 8; | ||||
} | } | ||||
static StringRef CurrentFilename; | static StringRef CurrentFilename; | ||||
static std::vector<NMSymbol> SymbolList; | static std::vector<NMSymbol> SymbolList; | ||||
▲ Show 20 Lines • Show All 690 Lines • ▼ Show 20 Lines | if (SegmentName == "__DATA" && SectionName == "__bss") | ||||
return 'b'; | return 'b'; | ||||
return 's'; | return 's'; | ||||
} | } | ||||
} | } | ||||
return '?'; | return '?'; | ||||
} | } | ||||
static char getSymbolNMTypeChar(TapiFile &Obj, basic_symbol_iterator I) { | |||||
return 's'; | |||||
} | |||||
static char getSymbolNMTypeChar(WasmObjectFile &Obj, basic_symbol_iterator I) { | static char getSymbolNMTypeChar(WasmObjectFile &Obj, basic_symbol_iterator I) { | ||||
uint32_t Flags = cantFail(I->getFlags()); | uint32_t Flags = cantFail(I->getFlags()); | ||||
if (Flags & SymbolRef::SF_Executable) | if (Flags & SymbolRef::SF_Executable) | ||||
return 't'; | return 't'; | ||||
return 'd'; | return 'd'; | ||||
} | } | ||||
static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I) { | static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I) { | ||||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | static char getNMSectionTagAndName(SymbolicFile &Obj, basic_symbol_iterator I, | ||||
else if (COFFObjectFile *COFF = dyn_cast<COFFObjectFile>(&Obj)) | else if (COFFObjectFile *COFF = dyn_cast<COFFObjectFile>(&Obj)) | ||||
Ret = getSymbolNMTypeChar(*COFF, I); | Ret = getSymbolNMTypeChar(*COFF, I); | ||||
else if (COFFImportFile *COFFImport = dyn_cast<COFFImportFile>(&Obj)) | else if (COFFImportFile *COFFImport = dyn_cast<COFFImportFile>(&Obj)) | ||||
Ret = getSymbolNMTypeChar(*COFFImport); | Ret = getSymbolNMTypeChar(*COFFImport); | ||||
else if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj)) | else if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj)) | ||||
Ret = getSymbolNMTypeChar(*MachO, I); | Ret = getSymbolNMTypeChar(*MachO, I); | ||||
else if (WasmObjectFile *Wasm = dyn_cast<WasmObjectFile>(&Obj)) | else if (WasmObjectFile *Wasm = dyn_cast<WasmObjectFile>(&Obj)) | ||||
Ret = getSymbolNMTypeChar(*Wasm, I); | Ret = getSymbolNMTypeChar(*Wasm, I); | ||||
else if (TapiFile *Tapi = dyn_cast<TapiFile>(&Obj)) | |||||
Ret = getSymbolNMTypeChar(*Tapi, I); | |||||
else if (ELFObjectFileBase *ELF = dyn_cast<ELFObjectFileBase>(&Obj)) { | else if (ELFObjectFileBase *ELF = dyn_cast<ELFObjectFileBase>(&Obj)) { | ||||
if (ELFSymbolRef(*I).getELFType() == ELF::STT_GNU_IFUNC) | if (ELFSymbolRef(*I).getELFType() == ELF::STT_GNU_IFUNC) | ||||
return 'i'; | return 'i'; | ||||
Ret = getSymbolNMTypeChar(*ELF, I); | Ret = getSymbolNMTypeChar(*ELF, I); | ||||
if (ELFSymbolRef(*I).getBinding() == ELF::STB_GNU_UNIQUE) | if (ELFSymbolRef(*I).getBinding() == ELF::STB_GNU_UNIQUE) | ||||
return Ret; | return Ret; | ||||
} else | } else | ||||
llvm_unreachable("unknown binary format"); | llvm_unreachable("unknown binary format"); | ||||
▲ Show 20 Lines • Show All 926 Lines • ▼ Show 20 Lines | for (const MachOUniversalBinary::ObjectForArch &O : UB->objects()) { | ||||
error(Filename + " for architecture " + | error(Filename + " for architecture " + | ||||
StringRef(O.getArchFlagName()) + | StringRef(O.getArchFlagName()) + | ||||
" is not a Mach-O file or an archive file", | " is not a Mach-O file or an archive file", | ||||
"Mach-O universal file"); | "Mach-O universal file"); | ||||
} | } | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
if (TapiUniversal *TU = dyn_cast<TapiUniversal>(&Bin)) { | |||||
for (const TapiUniversal::ObjectForArch &I : TU->objects()) { | |||||
jhenderson: Same comment as earlier - don't use `auto` where the type is not obvious from the immediate… | |||||
StringRef ArchName = I.getArchFlagName(); | |||||
const bool ShowArch = | |||||
ArchFlags.empty() || | |||||
any_of(ArchFlags, [&](StringRef Name) { return Name == ArchName; }); | |||||
Example why auto is bad: I'm assuming Name is actually a StringRef, in which case, you don't need the const & part of this, since StringRef is designed for lightweight copying. jhenderson: Example why `auto` is bad: I'm assuming Name is actually a `StringRef`, in which case, you… | |||||
if (!ShowArch) | |||||
continue; | |||||
if (!AddInlinedInfo && !I.isTopLevelLib()) | |||||
continue; | |||||
if (auto ObjOrErr = I.getAsObjectFile()) { | |||||
outs() << "\n" | |||||
I think you should be able to do: if (auto ObjOrErr = I.getAsObjectFile()) JDevlieghere: I think you should be able to do:
```
if (auto ObjOrErr = I.getAsObjectFile())
``` | |||||
Obj is only used once. Inline the variable to the call site MaskRay: Obj is only used once. Inline the variable to the call site | |||||
<< I.getInstallName() << " (for architecture " << ArchName << ")" | |||||
<< ":\n"; | |||||
dumpSymbolNamesFromObject(*ObjOrErr.get(), false, {}, ArchName); | |||||
} else if (Error E = | |||||
isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) { | |||||
auto -> Error MaskRay: auto -> Error | |||||
error(std::move(E), Filename, ArchName); | |||||
} | |||||
} | |||||
return; | |||||
} | |||||
if (SymbolicFile *O = dyn_cast<SymbolicFile>(&Bin)) { | if (SymbolicFile *O = dyn_cast<SymbolicFile>(&Bin)) { | ||||
if (!MachOPrintSizeWarning && PrintSize && isa<MachOObjectFile>(O)) { | if (!MachOPrintSizeWarning && PrintSize && isa<MachOObjectFile>(O)) { | ||||
WithColor::warning(errs(), ToolName) | WithColor::warning(errs(), ToolName) | ||||
<< "sizes with --print-size for Mach-O files are always zero.\n"; | << "sizes with --print-size for Mach-O files are always zero.\n"; | ||||
MachOPrintSizeWarning = true; | MachOPrintSizeWarning = true; | ||||
} | } | ||||
if (!checkMachOAndArchFlags(O, Filename)) | if (!checkMachOAndArchFlags(O, Filename)) | ||||
return; | return; | ||||
▲ Show 20 Lines • Show All 64 Lines • Show Last 20 Lines |
Same comment as earlier - don't use auto where the type is not obvious from the immediate context.