Index: llvm/include/llvm/Object/ELFObjectFile.h =================================================================== --- llvm/include/llvm/Object/ELFObjectFile.h +++ llvm/include/llvm/Object/ELFObjectFile.h @@ -61,6 +61,8 @@ StringRef getAMDGPUCPUName() const; protected: + bool ShowRawValue = false; + ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source); virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0; @@ -109,6 +111,10 @@ // corresponding to the section with that index. Expected> readBBAddrMap(std::optional TextSectionIndex = std::nullopt) const; + + void setShowRawValue(bool value) { ShowRawValue = value; } + + bool getShowRawValue() const { return ShowRawValue; } }; class ELFSectionRef : public SectionRef { @@ -556,6 +562,10 @@ if ((*SymOrErr)->st_shndx == ELF::SHN_ABS) return Ret; + // If raw value bool is set then emit raw value + if (getShowRawValue()) + return Ret; + const Elf_Ehdr &Header = EF.getHeader(); // Clear the ARM/Thumb or microMIPS indicator flag. if ((Header.e_machine == ELF::EM_ARM || Header.e_machine == ELF::EM_MIPS) && Index: llvm/test/tools/llvm-nm/ARM/address-check.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-nm/ARM/address-check.test @@ -0,0 +1,28 @@ +## Test for function type symbols with odd valued address to reflect raw value +## on ARM when --print-raw-values is used +# +# RUN: yaml2obj %s -o %t +# RUN: llvm-nm %t | FileCheck %s +# RUN: llvm-nm %t --print-raw-values | FileCheck %s --check-prefix=CHECKRAW + +!ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_ARM + Flags: [ EF_ARM_EABI_VER5 ] +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x4 +Symbols: + - Name: foo + Value: 0x1003 + Section: .text + Type: STT_FUNC + Binding: STB_GLOBAL + +# CHECK: 00001002 T foo +# CHECKRAW: 00001003 T foo Index: llvm/tools/llvm-nm/Opts.td =================================================================== --- llvm/tools/llvm-nm/Opts.td +++ llvm/tools/llvm-nm/Opts.td @@ -81,3 +81,6 @@ def : F<"v", "Alias for --numeric-sort">, Alias; def : F<"V", "Alias for --version">, Alias; def : F<"W", "Alias for --no-weak">, Alias; + +// ARM specific option +def print_raw_values: FF<"print-raw-values", "Print raw values for symbols">, Flags<[HelpHidden]>; Index: llvm/tools/llvm-nm/llvm-nm.cpp =================================================================== --- llvm/tools/llvm-nm/llvm-nm.cpp +++ llvm/tools/llvm-nm/llvm-nm.cpp @@ -130,6 +130,9 @@ static std::vector SegSect; static bool MachOPrintSizeWarning = false; +// ARM specific option. +static bool PrintRawValues = false; + // Miscellaneous states. static bool PrintAddress = true; static bool MultipleFiles = false; @@ -1815,6 +1818,8 @@ // see if this symbol is a symbol from that section and if not skip it. if (Nsect && Nsect != getNsectInMachO(*MachO, Sym)) continue; + if (ELFObj) + ELFObj->setShowRawValue(PrintRawValues); NMSymbol S = {}; S.Size = 0; S.Address = 0; @@ -2352,6 +2357,7 @@ PrintSize = Args.hasArg(OPT_print_size); ReverseSort = Args.hasArg(OPT_reverse_sort); ExportSymbols = Args.hasArg(OPT_export_symbols); + PrintRawValues = Args.hasArg(OPT_print_raw_values); if (ExportSymbols) { ExternalOnly = true; DefinedOnly = true;