[llvm] r361832 - [XCOFF] Implement parsing symbol table for xcoffobjfile and output as yaml format
Jason Liu via llvm-commits
llvm-commits at lists.llvm.org
Tue May 28 07:37:59 PDT 2019
Author: jasonliu
Date: Tue May 28 07:37:59 2019
New Revision: 361832
URL: http://llvm.org/viewvc/llvm-project?rev=361832&view=rev
Log:
[XCOFF] Implement parsing symbol table for xcoffobjfile and output as yaml format
Summary:
This patch implement parsing symbol table for xcoffobjfile and
output as yaml format. Parsing auxiliary entries of a symbol
will be in a separate patch.
The XCOFF object file (aix_xcoff.o) used in the test comes from
-bash-4.2$ cat test.c
extern int i;
extern int TestforXcoff;
int main()
{
i++;
TestforXcoff--;
}
Patch by DiggerLin
Reviewers: sfertile, hubert.reinterpretcast, MaskRay, daltenty
Differential Revision: https://reviews.llvm.org/D61532
Modified:
llvm/trunk/include/llvm/BinaryFormat/XCOFF.h
llvm/trunk/include/llvm/Object/XCOFFObjectFile.h
llvm/trunk/include/llvm/ObjectYAML/XCOFFYAML.h
llvm/trunk/lib/Object/XCOFFObjectFile.cpp
llvm/trunk/lib/ObjectYAML/XCOFFYAML.cpp
llvm/trunk/test/tools/obj2yaml/Inputs/aix_xcoff.o
llvm/trunk/test/tools/obj2yaml/aix_xcoff.test
llvm/trunk/tools/llvm-readobj/XCOFFDumper.cpp
llvm/trunk/tools/obj2yaml/xcoff2yaml.cpp
Modified: llvm/trunk/include/llvm/BinaryFormat/XCOFF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/XCOFF.h?rev=361832&r1=361831&r2=361832&view=diff
==============================================================================
--- llvm/trunk/include/llvm/BinaryFormat/XCOFF.h (original)
+++ llvm/trunk/include/llvm/BinaryFormat/XCOFF.h Tue May 28 07:37:59 2019
@@ -13,11 +13,14 @@
#ifndef LLVM_BINARYFORMAT_XCOFF_H
#define LLVM_BINARYFORMAT_XCOFF_H
+#include <cstdint>
+
namespace llvm {
namespace XCOFF {
// Constants used in the XCOFF definition.
-enum { SectionNameSize = 8 };
+enum { SectionNameSize = 8, SymbolNameSize = 8 };
+enum ReservedSectionNum { N_DEBUG = -2, N_ABS = -1, N_UNDEF = 0 };
// Flags for defining the section type. Used for the s_flags field of
// the section header structure. Defined in the system header `scnhdr.h`.
@@ -37,6 +40,75 @@ enum SectionTypeFlags {
STYP_OVRFLO = 0x8000
};
+// STORAGE CLASSES, n_sclass field of syment.
+// The values come from `storclass.h` and `dbxstclass.h`.
+enum StorageClass : uint8_t {
+ // Storage classes used for symbolic debugging symbols.
+ C_FILE = 103, // File name
+ C_BINCL = 108, // Beginning of include file
+ C_EINCL = 109, // Ending of include file
+ C_GSYM = 128, // Global variable
+ C_STSYM = 133, // Statically allocated symbol
+ C_BCOMM = 135, // Beginning of common block
+ C_ECOMM = 137, // End of common block
+ C_ENTRY = 141, // Alternate entry
+ C_BSTAT = 143, // Beginning of static block
+ C_ESTAT = 144, // End of static block
+ C_GTLS = 145, // Global thread-local variable
+ C_STTLS = 146, // Static thread-local variable
+
+ // Storage classes used for DWARF symbols.
+ C_DWARF = 112, // DWARF section symbol
+
+ // Storage classes used for absolute symbols.
+ C_LSYM = 129, // Automatic variable allocated on stack
+ C_PSYM = 130, // Argument to subroutine allocated on stack
+ C_RSYM = 131, // Register variable
+ C_RPSYM = 132, // Argument to function or procedure stored in register
+ C_ECOML = 136, // Local member of common block
+ C_FUN = 142, // Function or procedure
+
+ // Storage classes used for undefined external symbols or
+ // symbols of general sections.
+ C_EXT = 2, // External symbol
+ C_WEAKEXT = 111, // Weak external symbol
+
+ // Storage classes used for symbols of general sections.
+ C_NULL = 0,
+ C_STAT = 3, // Static
+ C_BLOCK = 100, // ".bb" or ".eb"
+ C_FCN = 101, // ".bf" or ".ef"
+ C_HIDEXT = 107, // Un-named external symbol
+ C_INFO = 110, // Comment string in .info section
+ C_DECL = 140, // Declaration of object (type)
+
+ // Storage classes - Obsolete/Undocumented.
+ C_AUTO = 1, // Automatic variable
+ C_REG = 4, // Register variable
+ C_EXTDEF = 5, // External definition
+ C_LABEL = 6, // Label
+ C_ULABEL = 7, // Undefined label
+ C_MOS = 8, // Member of structure
+ C_ARG = 9, // Function argument
+ C_STRTAG = 10, // Structure tag
+ C_MOU = 11, // Member of union
+ C_UNTAG = 12, // Union tag
+ C_TPDEF = 13, // Type definition
+ C_USTATIC = 14, // Undefined static
+ C_ENTAG = 15, // Enumeration tag
+ C_MOE = 16, // Member of enumeration
+ C_REGPARM = 17, // Register parameter
+ C_FIELD = 18, // Bit field
+ C_EOS = 102, // End of structure
+ C_LINE = 104,
+ C_ALIAS = 105, // Duplicate tag
+ C_HIDDEN = 106, // Special storage class for external
+ C_EFCN = 255, // Physical end of function
+
+ // Storage classes - reserved
+ C_TCSYM = 134 // Reserved
+};
+
} // end namespace XCOFF
} // end namespace llvm
Modified: llvm/trunk/include/llvm/Object/XCOFFObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/XCOFFObjectFile.h?rev=361832&r1=361831&r2=361832&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/XCOFFObjectFile.h (original)
+++ llvm/trunk/include/llvm/Object/XCOFFObjectFile.h Tue May 28 07:37:59 2019
@@ -61,16 +61,54 @@ struct XCOFFSectionHeader {
support::big32_t Flags;
};
+struct XCOFFSymbolEntry {
+ enum { NAME_IN_STR_TBL_MAGIC = 0x0 };
+ typedef struct {
+ support::big32_t Magic; // Zero indicates name in string table.
+ support::ubig32_t Offset;
+ } NameInStrTblType;
+
+ typedef struct {
+ uint8_t LanguageId;
+ uint8_t CpuTypeId;
+ } CFileLanguageIdAndTypeIdType;
+
+ union {
+ char SymbolName[XCOFF::SymbolNameSize];
+ NameInStrTblType NameInStrTbl;
+ };
+
+ support::ubig32_t Value; // Symbol value; storage class-dependent.
+ support::big16_t SectionNumber;
+
+ union {
+ support::ubig16_t SymbolType;
+ CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId;
+ };
+
+ XCOFF::StorageClass StorageClass;
+ uint8_t NumberOfAuxEntries;
+};
+
+struct XCOFFStringTable {
+ uint32_t Size;
+ const char *Data;
+};
+
class XCOFFObjectFile : public ObjectFile {
private:
const XCOFFFileHeader *FileHdrPtr = nullptr;
const XCOFFSectionHeader *SectionHdrTablePtr = nullptr;
+ const XCOFFSymbolEntry *SymbolTblPtr = nullptr;
+ XCOFFStringTable StringTable = {0, nullptr};
size_t getFileHeaderSize() const;
size_t getSectionHeaderSize() const;
const XCOFFSectionHeader *toSection(DataRefImpl Ref) const;
-
+ static bool isReservedSectionNumber(int16_t SectionNumber);
+ std::error_code getSectionByNum(int16_t Num,
+ const XCOFFSectionHeader *&Result) const;
public:
void moveSymbolNext(DataRefImpl &Symb) const override;
@@ -121,18 +159,27 @@ public:
XCOFFObjectFile(MemoryBufferRef Object, std::error_code &EC);
const XCOFFFileHeader *getFileHeader() const { return FileHdrPtr; }
+ const XCOFFSymbolEntry *getPointerToSymbolTable() const {
+ return SymbolTblPtr;
+ }
+
+ Expected<StringRef>
+ getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const;
+ const XCOFFSymbolEntry *toSymbolEntry(DataRefImpl Ref) const;
uint16_t getMagic() const;
uint16_t getNumberOfSections() const;
- int32_t getTimeStamp() const;
- uint32_t getSymbolTableOffset() const;
+ int32_t getTimeStamp() const;
+ uint32_t getSymbolTableOffset() const;
- // Note that this value is signed and might return a negative value. Negative
- // values are reserved for future use.
- int32_t getNumberOfSymbolTableEntries() const;
+ // Returns the value as encoded in the object file.
+ // Negative values are reserved for future use.
+ int32_t getRawNumberOfSymbolTableEntries() const;
+ // Returns a sanitized value, useable as an index into the symbol table.
+ uint32_t getLogicalNumberOfSymbolTableEntries() const;
uint16_t getOptionalHeaderSize() const;
- uint16_t getFlags() const;
+ uint16_t getFlags() const { return FileHdrPtr->Flags; };
}; // XCOFFObjectFile
} // namespace object
Modified: llvm/trunk/include/llvm/ObjectYAML/XCOFFYAML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/XCOFFYAML.h?rev=361832&r1=361831&r2=361832&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/XCOFFYAML.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/XCOFFYAML.h Tue May 28 07:37:59 2019
@@ -12,8 +12,9 @@
#ifndef LLVM_OBJECTYAML_XCOFFYAML_H
#define LLVM_OBJECTYAML_XCOFFYAML_H
+#include "llvm/BinaryFormat/XCOFF.h"
#include "llvm/ObjectYAML/YAML.h"
-#include <cstdint>
+#include <vector>
namespace llvm {
namespace XCOFFYAML {
@@ -28,14 +29,30 @@ struct FileHeader {
llvm::yaml::Hex16 Flags;
};
+struct Symbol {
+ StringRef SymbolName;
+ llvm::yaml::Hex32 Value; // Symbol value; storage class-dependent.
+ StringRef SectionName;
+ llvm::yaml::Hex16 Type;
+ XCOFF::StorageClass StorageClass;
+ uint8_t NumberOfAuxEntries; // Number of auxiliary entries
+};
+
struct Object {
FileHeader Header;
+ std::vector<Symbol> Symbols;
Object();
};
} // namespace XCOFFYAML
-
+} // namespace llvm
+LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Symbol)
+namespace llvm {
namespace yaml {
+template <> struct ScalarEnumerationTraits<XCOFF::StorageClass> {
+ static void enumeration(IO &IO, XCOFF::StorageClass &Value);
+};
+
template <> struct MappingTraits<XCOFFYAML::FileHeader> {
static void mapping(IO &IO, XCOFFYAML::FileHeader &H);
};
@@ -44,6 +61,10 @@ template <> struct MappingTraits<XCOFFYA
static void mapping(IO &IO, XCOFFYAML::Object &Obj);
};
+template <> struct MappingTraits<XCOFFYAML::Symbol> {
+ static void mapping(IO &IO, XCOFFYAML::Symbol &S);
+};
+
} // namespace yaml
} // namespace llvm
Modified: llvm/trunk/lib/Object/XCOFFObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/XCOFFObjectFile.cpp?rev=361832&r1=361831&r2=361832&view=diff
==============================================================================
--- llvm/trunk/lib/Object/XCOFFObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/XCOFFObjectFile.cpp Tue May 28 07:37:59 2019
@@ -26,6 +26,17 @@ enum { XCOFF32FileHeaderSize = 20 };
static_assert(sizeof(XCOFFFileHeader) == XCOFF32FileHeaderSize,
"Wrong size for XCOFF file header.");
+// Sets EC and returns false if there is less than 'Size' bytes left in the
+// buffer at 'Offset'.
+static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Offset,
+ uint64_t Size) {
+ if (M.getBufferSize() < Offset + Size) {
+ EC = object_error::unexpected_eof;
+ return false;
+ }
+ return true;
+}
+
// Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
// Returns unexpected_eof on error.
template <typename T>
@@ -43,6 +54,12 @@ template <typename T> static const T *vi
return reinterpret_cast<const T *>(in);
}
+static StringRef generateStringRef(const char *Name, uint64_t Size) {
+ auto NulCharPtr = static_cast<const char *>(memchr(Name, '\0', Size));
+ return NulCharPtr ? StringRef(Name, NulCharPtr - Name)
+ : StringRef(Name, Size);
+}
+
const XCOFFSectionHeader *XCOFFObjectFile::toSection(DataRefImpl Ref) const {
auto Sec = viewAs<XCOFFSectionHeader>(Ref.p);
#ifndef NDEBUG
@@ -58,6 +75,12 @@ const XCOFFSectionHeader *XCOFFObjectFil
return Sec;
}
+const XCOFFSymbolEntry *XCOFFObjectFile::toSymbolEntry(DataRefImpl Ref) const {
+ assert(Ref.p != 0 && "Symbol table pointer can not be nullptr!");
+ auto SymEntPtr = viewAs<XCOFFSymbolEntry>(Ref.p);
+ return SymEntPtr;
+}
+
// The next 2 functions are not exactly necessary yet, but they are useful to
// abstract over the size difference between XCOFF32 and XCOFF64 structure
// definitions.
@@ -69,15 +92,40 @@ size_t XCOFFObjectFile::getSectionHeader
return sizeof(XCOFFSectionHeader);
}
+uint16_t XCOFFObjectFile::getMagic() const { return FileHdrPtr->Magic; }
+
void XCOFFObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
- llvm_unreachable("Not yet implemented!");
- return;
+ const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
+
+ SymEntPtr += SymEntPtr->NumberOfAuxEntries + 1;
+ Symb.p = reinterpret_cast<uintptr_t>(SymEntPtr);
}
Expected<StringRef> XCOFFObjectFile::getSymbolName(DataRefImpl Symb) const {
- StringRef Result;
- llvm_unreachable("Not yet implemented!");
- return Result;
+ const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
+
+ if (SymEntPtr->NameInStrTbl.Magic != XCOFFSymbolEntry::NAME_IN_STR_TBL_MAGIC)
+ return generateStringRef(SymEntPtr->SymbolName, XCOFF::SymbolNameSize);
+
+ // A storage class value with the high-order bit on indicates that the name is
+ // a symbolic debugger stabstring.
+ if (SymEntPtr->StorageClass & 0x80)
+ return StringRef("Unimplemented Debug Name");
+
+ uint32_t Offset = SymEntPtr->NameInStrTbl.Offset;
+ // The byte offset is relative to the start of the string table
+ // or .debug section. A byte offset value of 0 is a null or zero-length symbol
+ // name. A byte offset in the range 1 to 3 (inclusive) points into the length
+ // field; as a soft-error recovery mechanism, we treat such cases as having an
+ // offset of 0.
+ if (Offset < 4)
+ return StringRef(nullptr, 0);
+
+ if (StringTable.Data != nullptr && StringTable.Size > Offset)
+ return (StringTable.Data + Offset);
+
+ return make_error<GenericBinaryError>("Symbol Name parse failed",
+ object_error::parse_failed);
}
Expected<uint64_t> XCOFFObjectFile::getSymbolAddress(DataRefImpl Symb) const {
@@ -87,9 +135,7 @@ Expected<uint64_t> XCOFFObjectFile::getS
}
uint64_t XCOFFObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
- uint64_t Result = 0;
- llvm_unreachable("Not yet implemented!");
- return Result;
+ return toSymbolEntry(Symb)->Value;
}
uint64_t XCOFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
@@ -106,8 +152,20 @@ XCOFFObjectFile::getSymbolType(DataRefIm
Expected<section_iterator>
XCOFFObjectFile::getSymbolSection(DataRefImpl Symb) const {
- llvm_unreachable("Not yet implemented!");
- return section_iterator(SectionRef());
+ const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
+ int16_t SectNum = SymEntPtr->SectionNumber;
+
+ if (isReservedSectionNumber(SectNum))
+ return section_end();
+
+ const XCOFFSectionHeader *Sec;
+ if (std::error_code EC = getSectionByNum(SectNum, Sec))
+ return errorCodeToError(EC);
+
+ DataRefImpl SecDRI;
+ SecDRI.p = reinterpret_cast<uintptr_t>(Sec);
+
+ return section_iterator(SectionRef(SecDRI, this));
}
void XCOFFObjectFile::moveSectionNext(DataRefImpl &Sec) const {
@@ -219,13 +277,16 @@ uint32_t XCOFFObjectFile::getSymbolFlags
}
basic_symbol_iterator XCOFFObjectFile::symbol_begin() const {
- llvm_unreachable("Not yet implemented!");
- return basic_symbol_iterator(SymbolRef());
+ DataRefImpl SymDRI;
+ SymDRI.p = reinterpret_cast<uintptr_t>(SymbolTblPtr);
+ return basic_symbol_iterator(SymbolRef(SymDRI, this));
}
basic_symbol_iterator XCOFFObjectFile::symbol_end() const {
- llvm_unreachable("Not yet implemented!");
- return basic_symbol_iterator(SymbolRef());
+ DataRefImpl SymDRI;
+ SymDRI.p = reinterpret_cast<uintptr_t>(
+ SymbolTblPtr + getLogicalNumberOfSymbolTableEntries());
+ return basic_symbol_iterator(SymbolRef(SymDRI, this));
}
section_iterator XCOFFObjectFile::section_begin() const {
@@ -243,7 +304,7 @@ section_iterator XCOFFObjectFile::sectio
uint8_t XCOFFObjectFile::getBytesInAddress() const {
// Only support 32-bit object files for now ...
- assert(getFileHeaderSize() == XCOFF32FileHeaderSize);
+ assert(getFileHeaderSize() == XCOFF32FileHeaderSize);
return 4;
}
@@ -274,6 +335,67 @@ Expected<uint64_t> XCOFFObjectFile::getS
return 0;
}
+std::error_code
+XCOFFObjectFile::getSectionByNum(int16_t Num,
+ const XCOFFSectionHeader *&Result) const {
+ if (Num > 0 && static_cast<uint16_t>(Num) <= getNumberOfSections()) {
+ Result = SectionHdrTablePtr + (Num - 1);
+ return std::error_code();
+ }
+
+ return object_error::invalid_section_index;
+}
+
+Expected<StringRef>
+XCOFFObjectFile::getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const {
+ int16_t SectionNum = SymEntPtr->SectionNumber;
+
+ switch (SectionNum) {
+ case XCOFF::N_DEBUG:
+ return "N_DEBUG";
+ case XCOFF::N_ABS:
+ return "N_ABS";
+ case XCOFF::N_UNDEF:
+ return "N_UNDEF";
+ default: {
+ const XCOFFSectionHeader *SectHeaderPtr;
+ std::error_code EC;
+ if ((EC = getSectionByNum(SectionNum, SectHeaderPtr)))
+ return errorCodeToError(EC);
+ else
+ return generateStringRef(SectHeaderPtr->Name, XCOFF::SectionNameSize);
+ }
+ }
+}
+
+bool XCOFFObjectFile::isReservedSectionNumber(int16_t SectionNumber) {
+ return (SectionNumber <= 0 && SectionNumber >= -2);
+}
+
+uint16_t XCOFFObjectFile::getNumberOfSections() const {
+ return FileHdrPtr->NumberOfSections;
+}
+
+int32_t XCOFFObjectFile::getTimeStamp() const { return FileHdrPtr->TimeStamp; }
+
+uint32_t XCOFFObjectFile::getSymbolTableOffset() const {
+ return FileHdrPtr->SymbolTableOffset;
+}
+
+int32_t XCOFFObjectFile::getRawNumberOfSymbolTableEntries() const {
+ return FileHdrPtr->NumberOfSymTableEntries;
+}
+
+uint32_t XCOFFObjectFile::getLogicalNumberOfSymbolTableEntries() const {
+ return (FileHdrPtr->NumberOfSymTableEntries >= 0
+ ? FileHdrPtr->NumberOfSymTableEntries
+ : 0);
+}
+
+uint16_t XCOFFObjectFile::getOptionalHeaderSize() const {
+ return FileHdrPtr->AuxHeaderSize;
+}
+
XCOFFObjectFile::XCOFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
: ObjectFile(Binary::ID_XCOFF32, Object) {
@@ -293,37 +415,39 @@ XCOFFObjectFile::XCOFFObjectFile(MemoryB
getNumberOfSections() * getSectionHeaderSize())))
return;
}
-}
-uint16_t XCOFFObjectFile::getMagic() const {
- return FileHdrPtr->Magic;
-}
+ if (getLogicalNumberOfSymbolTableEntries() == 0)
+ return;
-uint16_t XCOFFObjectFile::getNumberOfSections() const {
- return FileHdrPtr->NumberOfSections;
-}
+ // Get pointer to the symbol table.
+ CurPtr = FileHdrPtr->SymbolTableOffset;
+ uint64_t SymbolTableSize = (uint64_t)(sizeof(XCOFFSymbolEntry)) *
+ getLogicalNumberOfSymbolTableEntries();
-int32_t XCOFFObjectFile::getTimeStamp() const {
- return FileHdrPtr->TimeStamp;
-}
+ if ((EC = getObject(SymbolTblPtr, Data, base() + CurPtr, SymbolTableSize)))
+ return;
-uint32_t XCOFFObjectFile::getSymbolTableOffset() const {
- return FileHdrPtr->SymbolTableOffset;
-}
+ // Move pointer to the string table.
+ CurPtr += SymbolTableSize;
-int32_t XCOFFObjectFile::getNumberOfSymbolTableEntries() const {
- // As far as symbol table size is concerned, if this field is negative it is
- // to be treated as a 0. However since this field is also used for printing we
- // don't want to truncate any negative values.
- return FileHdrPtr->NumberOfSymTableEntries;
-}
+ if (CurPtr + 4 > Data.getBufferSize())
+ return;
-uint16_t XCOFFObjectFile::getOptionalHeaderSize() const {
- return FileHdrPtr->AuxHeaderSize;
-}
+ StringTable.Size = support::endian::read32be(base() + CurPtr);
+
+ if (StringTable.Size <= 4)
+ return;
+
+ // Check for whether the String table has the size indicated by length
+ // field
+ if (!checkSize(Data, EC, CurPtr, StringTable.Size))
+ return;
-uint16_t XCOFFObjectFile::getFlags() const {
- return FileHdrPtr->Flags;
+ StringTable.Data = reinterpret_cast<const char *>(base() + CurPtr);
+ if (StringTable.Data[StringTable.Size - 1] != '\0') {
+ EC = object_error::string_table_non_null_end;
+ return;
+ }
}
Expected<std::unique_ptr<ObjectFile>>
Modified: llvm/trunk/lib/ObjectYAML/XCOFFYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/XCOFFYAML.cpp?rev=361832&r1=361831&r2=361832&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/XCOFFYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/XCOFFYAML.cpp Tue May 28 07:37:59 2019
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ObjectYAML/XCOFFYAML.h"
+#include "llvm/BinaryFormat/XCOFF.h"
#include <string.h>
namespace llvm {
@@ -22,6 +23,62 @@ Object::Object() { memset(&Header, 0, si
namespace yaml {
+void ScalarEnumerationTraits<XCOFF::StorageClass>::enumeration(
+ IO &IO, XCOFF::StorageClass &Value) {
+#define ECase(X) IO.enumCase(Value, #X, XCOFF::X)
+ ECase(C_NULL);
+ ECase(C_AUTO);
+ ECase(C_EXT);
+ ECase(C_STAT);
+ ECase(C_REG);
+ ECase(C_EXTDEF);
+ ECase(C_LABEL);
+ ECase(C_ULABEL);
+ ECase(C_MOS);
+ ECase(C_ARG);
+ ECase(C_STRTAG);
+ ECase(C_MOU);
+ ECase(C_UNTAG);
+ ECase(C_TPDEF);
+ ECase(C_USTATIC);
+ ECase(C_ENTAG);
+ ECase(C_MOE);
+ ECase(C_REGPARM);
+ ECase(C_FIELD);
+ ECase(C_BLOCK);
+ ECase(C_FCN);
+ ECase(C_EOS);
+ ECase(C_FILE);
+ ECase(C_LINE);
+ ECase(C_ALIAS);
+ ECase(C_HIDDEN);
+ ECase(C_HIDEXT);
+ ECase(C_BINCL);
+ ECase(C_EINCL);
+ ECase(C_INFO);
+ ECase(C_WEAKEXT);
+ ECase(C_DWARF);
+ ECase(C_GSYM);
+ ECase(C_LSYM);
+ ECase(C_PSYM);
+ ECase(C_RSYM);
+ ECase(C_RPSYM);
+ ECase(C_STSYM);
+ ECase(C_TCSYM);
+ ECase(C_BCOMM);
+ ECase(C_ECOML);
+ ECase(C_ECOMM);
+ ECase(C_DECL);
+ ECase(C_ENTRY);
+ ECase(C_FUN);
+ ECase(C_BSTAT);
+ ECase(C_ESTAT);
+ ECase(C_GTLS);
+ ECase(C_STTLS);
+ ECase(C_EFCN);
+#undef ECase
+}
+
void MappingTraits<XCOFFYAML::FileHeader>::mapping(
IO &IO, XCOFFYAML::FileHeader &FileHdr) {
IO.mapRequired("MagicNumber", FileHdr.Magic);
@@ -33,9 +90,19 @@ void MappingTraits<XCOFFYAML::FileHeader
IO.mapRequired("Flags", FileHdr.Flags);
}
+void MappingTraits<XCOFFYAML::Symbol>::mapping(IO &IO, XCOFFYAML::Symbol &S) {
+ IO.mapRequired("Name", S.SymbolName);
+ IO.mapRequired("Value", S.Value);
+ IO.mapRequired("Section", S.SectionName);
+ IO.mapRequired("Type", S.Type);
+ IO.mapRequired("StorageClass", S.StorageClass);
+ IO.mapRequired("NumberOfAuxEntries", S.NumberOfAuxEntries);
+}
+
void MappingTraits<XCOFFYAML::Object>::mapping(IO &IO, XCOFFYAML::Object &Obj) {
IO.mapTag("!XCOFF", true);
IO.mapRequired("FileHeader", Obj.Header);
+ IO.mapRequired("Symbols", Obj.Symbols);
}
} // namespace yaml
Modified: llvm/trunk/test/tools/obj2yaml/Inputs/aix_xcoff.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/obj2yaml/Inputs/aix_xcoff.o?rev=361832&r1=361831&r2=361832&view=diff
==============================================================================
Binary files - no diff available.
Modified: llvm/trunk/test/tools/obj2yaml/aix_xcoff.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/obj2yaml/aix_xcoff.test?rev=361832&r1=361831&r2=361832&view=diff
==============================================================================
--- llvm/trunk/test/tools/obj2yaml/aix_xcoff.test (original)
+++ llvm/trunk/test/tools/obj2yaml/aix_xcoff.test Tue May 28 07:37:59 2019
@@ -2,10 +2,79 @@
# Test that we can parse the XCOFF object file correctly.
# CHECK: --- !XCOFF
# CHECK-NEXT: FileHeader:
-# CHECK-NEXT: MagicNumber: 0x01DF
-# CHECK-NEXT: NumberOfSections: 2
-# CHECK-NEXT: CreationTime: 1548692020
-# CHECK-NEXT: OffsetToSymbolTable: 0x00000108
-# CHECK-NEXT: EntriesInSymbolTable: 18
-# CHECK-NEXT: AuxiliaryHeaderSize: 0
-# CHECK-NEXT: Flags: 0x0000
+# CHECK-NEXT: MagicNumber: 0x01DF
+# CHECK-NEXT: NumberOfSections: 2
+# CHECK-NEXT: CreationTime: 1552337792
+# CHECK-NEXT: OffsetToSymbolTable: 0x0000013A
+# CHECK-NEXT: EntriesInSymbolTable: 22
+# CHECK-NEXT: AuxiliaryHeaderSize: 0
+# CHECK-NEXT: Flags: 0x0000
+
+# CHECK: Symbols:
+# CHECK-NEXT: - Name: .file
+# CHECK-NEXT: Value: 0x00000000
+# CHECK-NEXT: Section: N_DEBUG
+# CHECK-NEXT: Type: 0x0003
+# CHECK-NEXT: StorageClass: C_FILE
+# CHECK-NEXT: NumberOfAuxEntries: 1
+# CHECK-NEXT: - Name: i
+# CHECK-NEXT: Value: 0x00000000
+# CHECK-NEXT: Section: N_UNDEF
+# CHECK-NEXT: Type: 0x0000
+# CHECK-NEXT: StorageClass: C_EXT
+# CHECK-NEXT: NumberOfAuxEntries: 1
+# CHECK-NEXT: - Name: TestforXcoff
+# CHECK-NEXT: Value: 0x00000000
+# CHECK-NEXT: Section: N_UNDEF
+# CHECK-NEXT: Type: 0x0000
+# CHECK-NEXT: StorageClass: C_EXT
+# CHECK-NEXT: NumberOfAuxEntries: 1
+# CHECK-NEXT: - Name: .text
+# CHECK-NEXT: Value: 0x00000000
+# CHECK-NEXT: Section: .text
+# CHECK-NEXT: Type: 0x0000
+# CHECK-NEXT: StorageClass: C_HIDEXT
+# CHECK-NEXT: NumberOfAuxEntries: 1
+# CHECK-NEXT: - Name: .main
+# CHECK-NEXT: Value: 0x00000000
+# CHECK-NEXT: Section: .text
+# CHECK-NEXT: Type: 0x0000
+# CHECK-NEXT: StorageClass: C_EXT
+# CHECK-NEXT: NumberOfAuxEntries: 1
+# CHECK-NEXT: - Name: main
+# CHECK-NEXT: Value: 0x00000060
+# CHECK-NEXT: Section: .data
+# CHECK-NEXT: Type: 0x0000
+# CHECK-NEXT: StorageClass: C_HIDEXT
+# CHECK-NEXT: NumberOfAuxEntries: 1
+# CHECK-NEXT: - Name: main
+# CHECK-NEXT: Value: 0x00000060
+# CHECK-NEXT: Section: .data
+# CHECK-NEXT: Type: 0x0000
+# CHECK-NEXT: StorageClass: C_EXT
+# CHECK-NEXT: NumberOfAuxEntries: 1
+# CHECK-NEXT: - Name: .data
+# CHECK-NEXT: Value: 0x00000070
+# CHECK-NEXT: Section: .data
+# CHECK-NEXT: Type: 0x0000
+# CHECK-NEXT: StorageClass: C_HIDEXT
+# CHECK-NEXT: NumberOfAuxEntries: 1
+# CHECK-NEXT: - Name: TOC
+# CHECK-NEXT: Value: 0x00000074
+# CHECK-NEXT: Section: .data
+# CHECK-NEXT: Type: 0x0000
+# CHECK-NEXT: StorageClass: C_HIDEXT
+# CHECK-NEXT: NumberOfAuxEntries: 1
+# CHECK-NEXT: - Name: i
+# CHECK-NEXT: Value: 0x00000074
+# CHECK-NEXT: Section: .data
+# CHECK-NEXT: Type: 0x0000
+# CHECK-NEXT: StorageClass: C_HIDEXT
+# CHECK-NEXT: NumberOfAuxEntries: 1
+# CHECK-NEXT: - Name: TestforXcoff
+# CHECK-NEXT: Value: 0x00000078
+# CHECK-NEXT: Section: .data
+# CHECK-NEXT: Type: 0x0000
+# CHECK-NEXT: StorageClass: C_HIDEXT
+# CHECK-NEXT: NumberOfAuxEntries: 1
+# CHECK-NEXT: ...
Modified: llvm/trunk/tools/llvm-readobj/XCOFFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/XCOFFDumper.cpp?rev=361832&r1=361831&r2=361832&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/XCOFFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/XCOFFDumper.cpp Tue May 28 07:37:59 2019
@@ -66,7 +66,7 @@ void XCOFFDumper::printFileHeaders() {
}
W.printHex("SymbolTableOffset", Obj.getSymbolTableOffset());
- int32_t SymTabEntries = Obj.getNumberOfSymbolTableEntries();
+ int32_t SymTabEntries = Obj.getRawNumberOfSymbolTableEntries();
if (SymTabEntries >= 0)
W.printNumber("SymbolTableEntries", SymTabEntries);
else
Modified: llvm/trunk/tools/obj2yaml/xcoff2yaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/xcoff2yaml.cpp?rev=361832&r1=361831&r2=361832&view=diff
==============================================================================
--- llvm/trunk/tools/obj2yaml/xcoff2yaml.cpp (original)
+++ llvm/trunk/tools/obj2yaml/xcoff2yaml.cpp Tue May 28 07:37:59 2019
@@ -19,15 +19,20 @@ class XCOFFDumper {
const object::XCOFFObjectFile &Obj;
XCOFFYAML::Object YAMLObj;
void dumpHeader();
+ std::error_code dumpSymbols();
public:
- XCOFFDumper(const object::XCOFFObjectFile &obj);
+ XCOFFDumper(const object::XCOFFObjectFile &obj) : Obj(obj) {}
+ std::error_code dump();
XCOFFYAML::Object &getYAMLObj() { return YAMLObj; }
};
} // namespace
-XCOFFDumper::XCOFFDumper(const object::XCOFFObjectFile &obj) : Obj(obj) {
+std::error_code XCOFFDumper::dump() {
+ std::error_code EC;
dumpHeader();
+ EC = dumpSymbols();
+ return EC;
}
void XCOFFDumper::dumpHeader() {
@@ -42,9 +47,45 @@ void XCOFFDumper::dumpHeader() {
YAMLObj.Header.Flags = FileHdrPtr->Flags;
}
+std::error_code XCOFFDumper::dumpSymbols() {
+ std::vector<XCOFFYAML::Symbol> &Symbols = YAMLObj.Symbols;
+
+ for (const SymbolRef &S : Obj.symbols()) {
+ DataRefImpl SymbolDRI = S.getRawDataRefImpl();
+ const XCOFFSymbolEntry *SymbolEntPtr = Obj.toSymbolEntry(SymbolDRI);
+ XCOFFYAML::Symbol Sym;
+
+ Expected<StringRef> SymNameRefOrErr = Obj.getSymbolName(SymbolDRI);
+ if (!SymNameRefOrErr) {
+ return errorToErrorCode(SymNameRefOrErr.takeError());
+ }
+ Sym.SymbolName = SymNameRefOrErr.get();
+
+ Sym.Value = SymbolEntPtr->Value;
+
+ Expected<StringRef> SectionNameRefOrErr =
+ Obj.getSymbolSectionName(SymbolEntPtr);
+ if (!SectionNameRefOrErr)
+ return errorToErrorCode(SectionNameRefOrErr.takeError());
+
+ Sym.SectionName = SectionNameRefOrErr.get();
+
+ Sym.Type = SymbolEntPtr->SymbolType;
+ Sym.StorageClass = SymbolEntPtr->StorageClass;
+ Sym.NumberOfAuxEntries = SymbolEntPtr->NumberOfAuxEntries;
+ Symbols.push_back(Sym);
+ }
+
+ return std::error_code();
+}
+
std::error_code xcoff2yaml(raw_ostream &Out,
const object::XCOFFObjectFile &Obj) {
XCOFFDumper Dumper(Obj);
+
+ if (std::error_code EC = Dumper.dump())
+ return EC;
+
yaml::Output Yout(Out);
Yout << Dumper.getYAMLObj();
More information about the llvm-commits
mailing list