Object: Provide a richer means of describing auxiliary symbols
authorDavid Majnemer <david.majnemer@gmail.com>
Wed, 19 Mar 2014 04:47:47 +0000 (04:47 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Wed, 19 Mar 2014 04:47:47 +0000 (04:47 +0000)
The current state of affairs has auxiliary symbols described as a big
bag of bytes. This is less than satisfying, it detracts from the YAML
file as being human readable.

Instead, allow for symbols to optionally contain their auxiliary data.
This allows us to have a much higher level way of describing things like
weak symbols, function definitions and section definitions.

This depends on D3105.

Differential Revision: http://llvm-reviews.chandlerc.com/D3092

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204214 91177308-0d34-0410-b5e6-96231b3b80d8

14 files changed:
include/llvm/Object/COFF.h
include/llvm/Object/COFFYAML.h
include/llvm/Support/COFF.h
include/llvm/Support/YAMLTraits.h
lib/Object/COFFObjectFile.cpp
lib/Object/COFFYAML.cpp
test/Object/Inputs/COFF/i386.yaml
test/Object/Inputs/COFF/x86-64.yaml
test/Object/obj2yaml.test
tools/llvm-nm/llvm-nm.cpp
tools/llvm-objdump/llvm-objdump.cpp
tools/llvm-readobj/COFFDumper.cpp
tools/obj2yaml/coff2yaml.cpp
tools/yaml2obj/yaml2coff.cpp

index 4d5783ddceae712c9c7cf1c6b7248b1795018f9d..67afe35ae90e7a293f897433160fe4c8ebcba112 100644 (file)
@@ -202,6 +202,37 @@ struct coff_symbol {
   uint8_t getBaseType() const { return Type & 0x0F; }
 
   uint8_t getComplexType() const { return (Type & 0xF0) >> 4; }
+
+  bool isFunctionDefinition() const {
+    return StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
+           getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
+           getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION &&
+           COFF::isReservedSectionNumber(SectionNumber);
+  }
+
+  bool isWeakExternal() const {
+    return StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL ||
+           (StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
+            SectionNumber == COFF::IMAGE_SYM_UNDEFINED && Value == 0);
+  }
+
+  bool isFileRecord() const {
+    return StorageClass == COFF::IMAGE_SYM_CLASS_FILE;
+  }
+
+  bool isSectionDefinition() const {
+    // C++/CLI creates external ABS symbols for non-const appdomain globals.
+    // These are also followed by an auxiliary section definition.
+    bool isAppdomainGlobal = StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
+                             SectionNumber == COFF::IMAGE_SYM_ABSOLUTE;
+    bool isOrdinarySection =
+        StorageClass == COFF::IMAGE_SYM_CLASS_STATIC && Value == 0;
+    return isAppdomainGlobal || isOrdinarySection;
+  }
+
+  bool isCLRToken() const {
+    return StorageClass == COFF::IMAGE_SYM_CLASS_CLR_TOKEN;
+  }
 };
 
 struct coff_section {
index 3fa3ec6c124b131c745fdba21f19068d298178c4..b5f9cccf85d42828ae11bb801c4f645c403a71a8 100644 (file)
@@ -14,6 +14,7 @@
 #ifndef LLVM_OBJECT_COFFYAML_H
 #define LLVM_OBJECT_COFFYAML_H
 
+#include "llvm/ADT/Optional.h"
 #include "llvm/Object/YAML.h"
 #include "llvm/Support/COFF.h"
 
@@ -35,6 +36,10 @@ inline SectionCharacteristics operator|(SectionCharacteristics a,
 // The structure of the yaml files is not an exact 1:1 match to COFF. In order
 // to use yaml::IO, we use these structures which are closer to the source.
 namespace COFFYAML {
+  LLVM_YAML_STRONG_TYPEDEF(uint8_t, COMDATType)
+  LLVM_YAML_STRONG_TYPEDEF(uint32_t, WeakExternalCharacteristics)
+  LLVM_YAML_STRONG_TYPEDEF(uint8_t, AuxSymbolType)
+
   struct Relocation {
     uint32_t VirtualAddress;
     uint16_t Type;
@@ -54,7 +59,12 @@ namespace COFFYAML {
     COFF::symbol Header;
     COFF::SymbolBaseType SimpleType;
     COFF::SymbolComplexType ComplexType;
-    object::yaml::BinaryRef AuxiliaryData;
+    Optional<COFF::AuxiliaryFunctionDefinition> FunctionDefinition;
+    Optional<COFF::AuxiliarybfAndefSymbol> bfAndefSymbol;
+    Optional<COFF::AuxiliaryWeakExternal> WeakExternal;
+    StringRef File;
+    Optional<COFF::AuxiliarySectionDefinition> SectionDefinition;
+    Optional<COFF::AuxiliaryCLRToken> CLRToken;
     StringRef Name;
     Symbol();
   };
@@ -75,6 +85,21 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Relocation)
 namespace llvm {
 namespace yaml {
 
+template <>
+struct ScalarEnumerationTraits<COFFYAML::WeakExternalCharacteristics> {
+  static void enumeration(IO &IO, COFFYAML::WeakExternalCharacteristics &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<COFFYAML::AuxSymbolType> {
+  static void enumeration(IO &IO, COFFYAML::AuxSymbolType &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<COFFYAML::COMDATType> {
+  static void enumeration(IO &IO, COFFYAML::COMDATType &Value);
+};
+
 template <>
 struct ScalarEnumerationTraits<COFF::MachineTypes> {
   static void enumeration(IO &IO, COFF::MachineTypes &Value);
@@ -120,6 +145,26 @@ struct MappingTraits<COFF::header> {
   static void mapping(IO &IO, COFF::header &H);
 };
 
+template <> struct MappingTraits<COFF::AuxiliaryFunctionDefinition> {
+  static void mapping(IO &IO, COFF::AuxiliaryFunctionDefinition &AFD);
+};
+
+template <> struct MappingTraits<COFF::AuxiliarybfAndefSymbol> {
+  static void mapping(IO &IO, COFF::AuxiliarybfAndefSymbol &AAS);
+};
+
+template <> struct MappingTraits<COFF::AuxiliaryWeakExternal> {
+  static void mapping(IO &IO, COFF::AuxiliaryWeakExternal &AWE);
+};
+
+template <> struct MappingTraits<COFF::AuxiliarySectionDefinition> {
+  static void mapping(IO &IO, COFF::AuxiliarySectionDefinition &ASD);
+};
+
+template <> struct MappingTraits<COFF::AuxiliaryCLRToken> {
+  static void mapping(IO &IO, COFF::AuxiliaryCLRToken &ACT);
+};
+
 template <>
 struct MappingTraits<COFFYAML::Symbol> {
   static void mapping(IO &IO, COFFYAML::Symbol &S);
index 558625330911fda911ebeeabdcaed153e0a960d9..dca7fc6ee8984cc4c440ea1b377c3e2615bdf867 100644 (file)
@@ -212,6 +212,10 @@ namespace COFF {
     SCT_COMPLEX_TYPE_SHIFT   = 4
   };
 
+  enum AuxSymbolType {
+    IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF = 1
+  };
+
   struct section {
     char     Name[NameSize];
     uint32_t VirtualSize;
@@ -337,7 +341,7 @@ namespace COFF {
     uint32_t TotalSize;
     uint32_t PointerToLinenumber;
     uint32_t PointerToNextFunction;
-    uint8_t  unused[2];
+    char     unused[2];
   };
 
   struct AuxiliarybfAndefSymbol {
@@ -372,7 +376,14 @@ namespace COFF {
     uint32_t CheckSum;
     uint16_t Number;
     uint8_t  Selection;
-    uint8_t  unused[3];
+    char     unused[3];
+  };
+
+  struct AuxiliaryCLRToken {
+    uint8_t  AuxType;
+    uint8_t  unused1;
+    uint32_t SymbolTableIndex;
+    char     unused2[12];
   };
 
   union Auxiliary {
index e704bf17fe175f12f8932c8b4a324bbcaa31a540..ea217c39fca20359efd1f31070b2b4f9c2a19c3f 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
@@ -420,6 +421,11 @@ public:
     this->processKey(Key, Val, false);
   }
 
+  template <typename T>
+  void mapOptional(const char* Key, Optional<T> &Val) {
+    processKeyWithDefault(Key, Val, Optional<T>(), /*Required=*/false);
+  }
+
   template <typename T>
   typename std::enable_if<!has_SequenceTraits<T>::value,void>::type
   mapOptional(const char* Key, T& Val) {
@@ -432,6 +438,26 @@ public:
   }
   
 private:
+  template <typename T>
+  void processKeyWithDefault(const char *Key, Optional<T> &Val,
+                             const Optional<T> &DefaultValue, bool Required) {
+    assert(DefaultValue.hasValue() == false &&
+           "Optional<T> shouldn't have a value!");
+    void *SaveInfo;
+    bool UseDefault;
+    const bool sameAsDefault = outputting() && !Val.hasValue();
+    if (!outputting() && !Val.hasValue())
+      Val = T();
+    if (this->preflightKey(Key, Required, sameAsDefault, UseDefault,
+                           SaveInfo)) {
+      yamlize(*this, Val.getValue(), Required);
+      this->postflightKey(SaveInfo);
+    } else {
+      if (UseDefault)
+        Val = DefaultValue;
+    }
+  }
+
   template <typename T>
   void processKeyWithDefault(const char *Key, T &Val, const T& DefaultValue,
                                                                 bool Required) {
index 039bc4ef48b97951355eb349e7f5644780e58c5a..8036ab181273312a7a008e10fe4efb46bfce1257 100644 (file)
@@ -174,7 +174,7 @@ error_code COFFObjectFile::getSymbolType(DataRefImpl Ref,
   if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
       Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) {
     Result = SymbolRef::ST_Unknown;
-  } else if (Symb->getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION) {
+  } else if (Symb->isFunctionDefinition()) {
     Result = SymbolRef::ST_Function;
   } else {
     uint32_t Characteristics = 0;
index 2a0c07a391aaea0ec6155310165374ab84ca9726..94b72ffcbf3f861d2e06a81bc15fccdedf203f79 100644 (file)
@@ -23,6 +23,31 @@ Object::Object() { memset(&Header, 0, sizeof(COFF::header)); }
 }
 
 namespace yaml {
+void ScalarEnumerationTraits<COFFYAML::COMDATType>::enumeration(
+    IO &IO, COFFYAML::COMDATType &Value) {
+  IO.enumCase(Value, "0", 0);
+  ECase(IMAGE_COMDAT_SELECT_NODUPLICATES);
+  ECase(IMAGE_COMDAT_SELECT_ANY);
+  ECase(IMAGE_COMDAT_SELECT_SAME_SIZE);
+  ECase(IMAGE_COMDAT_SELECT_EXACT_MATCH);
+  ECase(IMAGE_COMDAT_SELECT_ASSOCIATIVE);
+  ECase(IMAGE_COMDAT_SELECT_LARGEST);
+  ECase(IMAGE_COMDAT_SELECT_NEWEST);
+}
+
+void
+ScalarEnumerationTraits<COFFYAML::WeakExternalCharacteristics>::enumeration(
+    IO &IO, COFFYAML::WeakExternalCharacteristics &Value) {
+  ECase(IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
+  ECase(IMAGE_WEAK_EXTERN_SEARCH_LIBRARY);
+  ECase(IMAGE_WEAK_EXTERN_SEARCH_ALIAS);
+}
+
+void ScalarEnumerationTraits<COFFYAML::AuxSymbolType>::enumeration(
+    IO &IO, COFFYAML::AuxSymbolType &Value) {
+  ECase(IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF);
+}
+
 void ScalarEnumerationTraits<COFF::MachineTypes>::enumeration(
     IO &IO, COFF::MachineTypes &Value) {
   ECase(IMAGE_FILE_MACHINE_UNKNOWN);
@@ -187,6 +212,24 @@ void ScalarBitSetTraits<COFF::SectionCharacteristics>::bitset(
 #undef BCase
 
 namespace {
+struct NSectionSelectionType {
+  NSectionSelectionType(IO &)
+      : SelectionType(COFFYAML::COMDATType(0)) {}
+  NSectionSelectionType(IO &, uint8_t C)
+      : SelectionType(COFFYAML::COMDATType(C)) {}
+  uint8_t denormalize(IO &) { return SelectionType; }
+  COFFYAML::COMDATType SelectionType;
+};
+
+struct NWeakExternalCharacteristics {
+  NWeakExternalCharacteristics(IO &)
+      : Characteristics(COFFYAML::WeakExternalCharacteristics(0)) {}
+  NWeakExternalCharacteristics(IO &, uint32_t C)
+      : Characteristics(COFFYAML::WeakExternalCharacteristics(C)) {}
+  uint32_t denormalize(IO &) { return Characteristics; }
+  COFFYAML::WeakExternalCharacteristics Characteristics;
+};
+
 struct NSectionCharacteristics {
   NSectionCharacteristics(IO &)
       : Characteristics(COFF::SectionCharacteristics(0)) {}
@@ -196,6 +239,15 @@ struct NSectionCharacteristics {
   COFF::SectionCharacteristics Characteristics;
 };
 
+struct NAuxTokenType {
+  NAuxTokenType(IO &)
+      : AuxType(COFFYAML::AuxSymbolType(0)) {}
+  NAuxTokenType(IO &, uint8_t C)
+      : AuxType(COFFYAML::AuxSymbolType(C)) {}
+  uint32_t denormalize(IO &) { return AuxType; }
+  COFFYAML::AuxSymbolType AuxType;
+};
+
 struct NStorageClass {
   NStorageClass(IO &) : StorageClass(COFF::SymbolStorageClass(0)) {}
   NStorageClass(IO &, uint8_t S) : StorageClass(COFF::SymbolStorageClass(S)) {}
@@ -247,6 +299,48 @@ void MappingTraits<COFF::header>::mapping(IO &IO, COFF::header &H) {
   IO.mapOptional("Characteristics", NC->Characteristics);
 }
 
+void MappingTraits<COFF::AuxiliaryFunctionDefinition>::mapping(
+    IO &IO, COFF::AuxiliaryFunctionDefinition &AFD) {
+  IO.mapRequired("TagIndex", AFD.TagIndex);
+  IO.mapRequired("TotalSize", AFD.TotalSize);
+  IO.mapRequired("PointerToLinenumber", AFD.PointerToLinenumber);
+  IO.mapRequired("PointerToNextFunction", AFD.PointerToNextFunction);
+}
+
+void MappingTraits<COFF::AuxiliarybfAndefSymbol>::mapping(
+    IO &IO, COFF::AuxiliarybfAndefSymbol &AAS) {
+  IO.mapRequired("Linenumber", AAS.Linenumber);
+  IO.mapRequired("PointerToNextFunction", AAS.PointerToNextFunction);
+}
+
+void MappingTraits<COFF::AuxiliaryWeakExternal>::mapping(
+    IO &IO, COFF::AuxiliaryWeakExternal &AWE) {
+  MappingNormalization<NWeakExternalCharacteristics, uint32_t> NWEC(
+      IO, AWE.Characteristics);
+  IO.mapRequired("TagIndex", AWE.TagIndex);
+  IO.mapRequired("Characteristics", NWEC->Characteristics);
+}
+
+void MappingTraits<COFF::AuxiliarySectionDefinition>::mapping(
+    IO &IO, COFF::AuxiliarySectionDefinition &ASD) {
+  MappingNormalization<NSectionSelectionType, uint8_t> NSST(
+      IO, ASD.Selection);
+
+  IO.mapRequired("Length", ASD.Length);
+  IO.mapRequired("NumberOfRelocations", ASD.NumberOfRelocations);
+  IO.mapRequired("NumberOfLinenumbers", ASD.NumberOfLinenumbers);
+  IO.mapRequired("CheckSum", ASD.CheckSum);
+  IO.mapRequired("Number", ASD.Number);
+  IO.mapOptional("Selection", NSST->SelectionType, COFFYAML::COMDATType(0));
+}
+
+void MappingTraits<COFF::AuxiliaryCLRToken>::mapping(
+    IO &IO, COFF::AuxiliaryCLRToken &ACT) {
+  MappingNormalization<NAuxTokenType, uint8_t> NATT(IO, ACT.AuxType);
+  IO.mapRequired("AuxType", NATT->AuxType);
+  IO.mapRequired("SymbolTableIndex", ACT.SymbolTableIndex);
+}
+
 void MappingTraits<COFFYAML::Symbol>::mapping(IO &IO, COFFYAML::Symbol &S) {
   MappingNormalization<NStorageClass, uint8_t> NS(IO, S.Header.StorageClass);
 
@@ -256,9 +350,12 @@ void MappingTraits<COFFYAML::Symbol>::mapping(IO &IO, COFFYAML::Symbol &S) {
   IO.mapRequired("SimpleType", S.SimpleType);
   IO.mapRequired("ComplexType", S.ComplexType);
   IO.mapRequired("StorageClass", NS->StorageClass);
-  IO.mapOptional("NumberOfAuxSymbols", S.Header.NumberOfAuxSymbols,
-                 (uint8_t) 0);
-  IO.mapOptional("AuxiliaryData", S.AuxiliaryData, object::yaml::BinaryRef());
+  IO.mapOptional("FunctionDefinition", S.FunctionDefinition);
+  IO.mapOptional("bfAndefSymbol", S.bfAndefSymbol);
+  IO.mapOptional("WeakExternal", S.WeakExternal);
+  IO.mapOptional("File", S.File, StringRef());
+  IO.mapOptional("SectionDefinition", S.SectionDefinition);
+  IO.mapOptional("CLRToken", S.CLRToken);
 }
 
 void MappingTraits<COFFYAML::Section>::mapping(IO &IO, COFFYAML::Section &Sec) {
index 1badad8d5915b88c0ee215d5705c3b88dd81ff9b..7873df0a7e25d6be7cb16bd0d5dc18ef5221eef1 100644 (file)
@@ -39,8 +39,12 @@ symbols:
     SimpleType: IMAGE_SYM_TYPE_NULL # (0)
     ComplexType: IMAGE_SYM_DTYPE_NULL # (0)
     StorageClass: IMAGE_SYM_CLASS_STATIC # (3)
-    NumberOfAuxSymbols: 1
-    AuxiliaryData:  !hex "240000000300000000000000010000000000" # |$.................|
+    SectionDefinition:
+      Length:          36
+      NumberOfRelocations: 3
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          1
 
   - !Symbol
     Name: .data
@@ -49,8 +53,12 @@ symbols:
     SimpleType: IMAGE_SYM_TYPE_NULL # (0)
     ComplexType: IMAGE_SYM_DTYPE_NULL # (0)
     StorageClass: IMAGE_SYM_CLASS_STATIC # (3)
-    NumberOfAuxSymbols: 1
-    AuxiliaryData:  !hex "0D0000000000000000000000020000000000" # |..................|
+    SectionDefinition:
+      Length:          13
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          2
 
   - !Symbol
     Name: _main
index b775ae9cdfbdbcc0ae87bf7d33d2745c5207dd28..1dc2b10cf4105bd90315c02e2c5a96e5c476a792 100644 (file)
@@ -38,8 +38,12 @@ symbols:
     SimpleType: IMAGE_SYM_TYPE_NULL # (0)
     ComplexType: IMAGE_SYM_DTYPE_NULL # (0)
     StorageClass: IMAGE_SYM_CLASS_STATIC # (3)
-    NumberOfAuxSymbols: 1
-    AuxiliaryData:  !hex "260000000300000000000000010000000000" # |&.................|
+    SectionDefinition:
+      Length:          38
+      NumberOfRelocations: 3
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          1
 
   - !Symbol
     Name: .data
@@ -48,8 +52,12 @@ symbols:
     SimpleType: IMAGE_SYM_TYPE_NULL # (0)
     ComplexType: IMAGE_SYM_DTYPE_NULL # (0)
     StorageClass: IMAGE_SYM_CLASS_STATIC # (3)
-    NumberOfAuxSymbols: 1
-    AuxiliaryData:  !hex "0D0000000000000000000000020000000000" # |..................|
+    SectionDefinition:
+      Length:          13
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          2
 
   - !Symbol
     Name: main
index 49541336c682637dccfc177415d40e142101ab57..d96275fe2cc112970286cf0c98571bf9be37e983 100644 (file)
@@ -36,8 +36,12 @@ COFF-I386-NEXT:    SectionNumber: 1
 COFF-I386-NEXT:    SimpleType: IMAGE_SYM_TYPE_NULL
 COFF-I386-NEXT:    ComplexType: IMAGE_SYM_DTYPE_NULL
 COFF-I386-NEXT:    StorageClass: IMAGE_SYM_CLASS_STATIC
-COFF-I386-NEXT:    NumberOfAuxSymbols: 1
-COFF-I386-NEXT:    AuxiliaryData: 240000000300000000000000010000000000
+COFF-I386-NEXT:    SectionDefinition:
+COFF-I386-NEXT:      Length:          36
+COFF-I386-NEXT:      NumberOfRelocations: 3
+COFF-I386-NEXT:      NumberOfLinenumbers: 0
+COFF-I386-NEXT:      CheckSum:        0
+COFF-I386-NEXT:      Number:          1
 
 COFF-I386:       - Name: .data
 COFF-I386-NEXT:    Value: 0
@@ -45,8 +49,12 @@ COFF-I386-NEXT:    SectionNumber: 2
 COFF-I386-NEXT:    SimpleType: IMAGE_SYM_TYPE_NULL
 COFF-I386-NEXT:    ComplexType: IMAGE_SYM_DTYPE_NULL
 COFF-I386-NEXT:    StorageClass: IMAGE_SYM_CLASS_STATIC
-COFF-I386-NEXT:    NumberOfAuxSymbols: 1
-COFF-I386-NEXT:    AuxiliaryData: 0D0000000000000000000000020000000000
+COFF-I386-NEXT:    SectionDefinition:
+COFF-I386-NEXT:      Length:          13
+COFF-I386-NEXT:      NumberOfRelocations: 0
+COFF-I386-NEXT:      NumberOfLinenumbers: 0
+COFF-I386-NEXT:      CheckSum:        0
+COFF-I386-NEXT:      Number:          2
 
 COFF-I386:       - Name: _main
 COFF-I386-NEXT:    Value: 0
@@ -111,8 +119,12 @@ COFF-X86-64-NEXT:     SectionNumber: 1
 COFF-X86-64-NEXT:     SimpleType: IMAGE_SYM_TYPE_NULL
 COFF-X86-64-NEXT:     ComplexType: IMAGE_SYM_DTYPE_NULL
 COFF-X86-64-NEXT:     StorageClass: IMAGE_SYM_CLASS_STATIC
-COFF-X86-64-NEXT:     NumberOfAuxSymbols: 1
-COFF-X86-64-NEXT:     AuxiliaryData: 260000000300000000000000010000000000
+COFF-X86-64-NEXT:    SectionDefinition:
+COFF-X86-64-NEXT:      Length:          38
+COFF-X86-64-NEXT:      NumberOfRelocations: 3
+COFF-X86-64-NEXT:      NumberOfLinenumbers: 0
+COFF-X86-64-NEXT:      CheckSum:        0
+COFF-X86-64-NEXT:      Number:          1
 
 COFF-X86-64:        - Name: .data
 COFF-X86-64-NEXT:     Value: 0
@@ -120,8 +132,12 @@ COFF-X86-64-NEXT:     SectionNumber: 2
 COFF-X86-64-NEXT:     SimpleType: IMAGE_SYM_TYPE_NULL
 COFF-X86-64-NEXT:     ComplexType: IMAGE_SYM_DTYPE_NULL
 COFF-X86-64-NEXT:     StorageClass: IMAGE_SYM_CLASS_STATIC
-COFF-X86-64-NEXT:     NumberOfAuxSymbols: 1
-COFF-X86-64-NEXT:     AuxiliaryData: 0D0000000000000000000000020000000000
+COFF-X86-64-NEXT:    SectionDefinition:
+COFF-X86-64-NEXT:      Length:          13
+COFF-X86-64-NEXT:      NumberOfRelocations: 0
+COFF-X86-64-NEXT:      NumberOfLinenumbers: 0
+COFF-X86-64-NEXT:      CheckSum:        0
+COFF-X86-64-NEXT:      Number:          2
 
 COFF-X86-64:        - Name: main
 COFF-X86-64-NEXT:     Value: 0
index 100a1f20a118ddb7965a482cff4b101f7bd22845..22e019a8a527a79150c07bc2e8a3f4b61d62bccf 100644 (file)
@@ -344,8 +344,7 @@ static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) {
       return 'i';
 
     // Check for section symbol.
-    else if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC &&
-             Symb->Value == 0)
+    else if (Symb->isSectionDefinition())
       return 's';
   }
 
index 3f871471bca4a68971a3ec82d7021d0002c5916d..f5328a959e91a40de48ca6cebf2d22d0951d8876 100644 (file)
@@ -663,8 +663,7 @@ static void PrintCOFFSymbolTable(const COFFObjectFile *coff) {
   for (int i = 0, e = header->NumberOfSymbols; i != e; ++i) {
     if (aux_count--) {
       // Figure out which type of aux this is.
-      if (symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC
-          && symbol->Value == 0) { // Section definition.
+      if (symbol->isSectionDefinition()) { // Section definition.
         const coff_aux_section_definition *asd;
         if (error(coff->getAuxSymbol<coff_aux_section_definition>(i, asd)))
           return;
index d2275f0aab8f6fa4abcc3968ec28a4d27e918137..cd40da7d6cc291bd6336a065e3de5fb9f51d4fe3 100644 (file)
@@ -946,12 +946,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) {
   W.printNumber("AuxSymbolCount", Symbol->NumberOfAuxSymbols);
 
   for (unsigned I = 0; I < Symbol->NumberOfAuxSymbols; ++I) {
-    if (Symbol->StorageClass     == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
-        Symbol->getBaseType()    == COFF::IMAGE_SYM_TYPE_NULL &&
-        Symbol->getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION &&
-        Symbol->SectionNumber != COFF::IMAGE_SYM_DEBUG &&
-        Symbol->SectionNumber != COFF::IMAGE_SYM_ABSOLUTE &&
-        Symbol->SectionNumber != COFF::IMAGE_SYM_UNDEFINED) {
+    if (Symbol->isFunctionDefinition()) {
       const coff_aux_function_definition *Aux;
       if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
         break;
@@ -963,11 +958,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) {
       W.printHex("PointerToNextFunction", Aux->PointerToNextFunction);
       W.printBinary("Unused", makeArrayRef(Aux->Unused));
 
-    } else if (
-        Symbol->StorageClass   == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL ||
-        (Symbol->StorageClass  == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
-         Symbol->SectionNumber == COFF::IMAGE_SYM_UNDEFINED &&
-         Symbol->Value         == 0)) {
+    } else if (Symbol->isWeakExternal()) {
       const coff_aux_weak_external *Aux;
       if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
         break;
@@ -987,7 +978,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) {
                     makeArrayRef(WeakExternalCharacteristics));
       W.printBinary("Unused", makeArrayRef(Aux->Unused));
 
-    } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_FILE) {
+    } else if (Symbol->isFileRecord()) {
       const coff_aux_file_record *Aux;
       if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
         break;
@@ -995,11 +986,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) {
       DictScope AS(W, "AuxFileRecord");
       W.printString("FileName", StringRef(Aux->FileName));
 
-    // C++/CLI creates external ABS symbols for non-const appdomain globals.
-    // These are also followed by an auxiliary section definition.
-    } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC ||
-               (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
-                Symbol->SectionNumber == COFF::IMAGE_SYM_ABSOLUTE)) {
+    } else if (Symbol->isSectionDefinition()) {
       const coff_aux_section_definition *Aux;
       if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
         break;
@@ -1026,7 +1013,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) {
 
         W.printNumber("AssocSection", AssocName, Aux->Number);
       }
-    } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_CLR_TOKEN) {
+    } else if (Symbol->isCLRToken()) {
       const coff_aux_clr_token *Aux;
       if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
         break;
index 6cf79aeabc7d9a4d873a438fbac6b4b7b4201726..b003029407ca71d25473845ef2f3e2483761c489 100644 (file)
@@ -78,6 +78,61 @@ void COFFDumper::dumpSections(unsigned NumSections) {
   }
 }
 
+static void
+dumpFunctionDefinition(COFFYAML::Symbol *Sym,
+                       const object::coff_aux_function_definition *ObjFD) {
+  COFF::AuxiliaryFunctionDefinition YAMLFD;
+  YAMLFD.TagIndex = ObjFD->TagIndex;
+  YAMLFD.TotalSize = ObjFD->TotalSize;
+  YAMLFD.PointerToLinenumber = ObjFD->PointerToLinenumber;
+  YAMLFD.PointerToNextFunction = ObjFD->PointerToNextFunction;
+
+  Sym->FunctionDefinition = YAMLFD;
+}
+
+static void
+dumpbfAndEfLineInfo(COFFYAML::Symbol *Sym,
+                    const object::coff_aux_bf_and_ef_symbol *ObjBES) {
+  COFF::AuxiliarybfAndefSymbol YAMLAAS;
+  YAMLAAS.Linenumber = ObjBES->Linenumber;
+  YAMLAAS.PointerToNextFunction = ObjBES->PointerToNextFunction;
+
+  Sym->bfAndefSymbol = YAMLAAS;
+}
+
+static void dumpWeakExternal(COFFYAML::Symbol *Sym,
+                             const object::coff_aux_weak_external *ObjWE) {
+  COFF::AuxiliaryWeakExternal YAMLWE;
+  YAMLWE.TagIndex = ObjWE->TagIndex;
+  YAMLWE.Characteristics = ObjWE->Characteristics;
+
+  Sym->WeakExternal = YAMLWE;
+}
+
+static void
+dumpSectionDefinition(COFFYAML::Symbol *Sym,
+                      const object::coff_aux_section_definition *ObjSD) {
+  COFF::AuxiliarySectionDefinition YAMLASD;
+  YAMLASD.Length = ObjSD->Length;
+  YAMLASD.NumberOfRelocations = ObjSD->NumberOfRelocations;
+  YAMLASD.NumberOfLinenumbers = ObjSD->NumberOfLinenumbers;
+  YAMLASD.CheckSum = ObjSD->CheckSum;
+  YAMLASD.Number = ObjSD->Number;
+  YAMLASD.Selection = ObjSD->Selection;
+
+  Sym->SectionDefinition = YAMLASD;
+}
+
+static void
+dumpCLRTokenDefinition(COFFYAML::Symbol *Sym,
+                       const object::coff_aux_clr_token *ObjCLRToken) {
+  COFF::AuxiliaryCLRToken YAMLCLRToken;
+  YAMLCLRToken.AuxType = ObjCLRToken->AuxType;
+  YAMLCLRToken.SymbolTableIndex = ObjCLRToken->SymbolTableIndex;
+
+  Sym->CLRToken = YAMLCLRToken;
+}
+
 void COFFDumper::dumpSymbols(unsigned NumSymbols) {
   std::vector<COFFYAML::Symbol> &Symbols = YAMLObj.Symbols;
   for (const auto &S : Obj.symbols()) {
@@ -90,7 +145,62 @@ void COFFDumper::dumpSymbols(unsigned NumSymbols) {
     Sym.Header.Value = Symbol->Value;
     Sym.Header.SectionNumber = Symbol->SectionNumber;
     Sym.Header.NumberOfAuxSymbols = Symbol->NumberOfAuxSymbols;
-    Sym.AuxiliaryData = object::yaml::BinaryRef(Obj.getSymbolAuxData(Symbol));
+
+    if (Symbol->NumberOfAuxSymbols > 0) {
+      ArrayRef<uint8_t> AuxData = Obj.getSymbolAuxData(Symbol);
+      if (Symbol->isFunctionDefinition()) {
+        // This symbol represents a function definition.
+        assert(Symbol->NumberOfAuxSymbols == 1 &&
+               "Expected a single aux symbol to describe this function!");
+
+        const object::coff_aux_function_definition *ObjFD =
+            reinterpret_cast<const object::coff_aux_function_definition *>(
+                AuxData.data());
+        dumpFunctionDefinition(&Sym, ObjFD);
+      } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_FUNCTION) {
+        // This symbol describes function line number information.
+        assert(Symbol->NumberOfAuxSymbols == 1 &&
+               "Exepected a single aux symbol to describe this section!");
+
+        const object::coff_aux_bf_and_ef_symbol *ObjBES =
+            reinterpret_cast<const object::coff_aux_bf_and_ef_symbol *>(
+                AuxData.data());
+        dumpbfAndEfLineInfo(&Sym, ObjBES);
+      } else if (Symbol->isWeakExternal()) {
+        // This symbol represents a weak external definition.
+        assert(Symbol->NumberOfAuxSymbols == 1 &&
+               "Exepected a single aux symbol to describe this section!");
+
+        const object::coff_aux_weak_external *ObjWE =
+            reinterpret_cast<const object::coff_aux_weak_external *>(
+                AuxData.data());
+        dumpWeakExternal(&Sym, ObjWE);
+      } else if (Symbol->isFileRecord()) {
+        // This symbol represents a file record.
+        Sym.File = StringRef(reinterpret_cast<const char *>(AuxData.data()),
+                             Symbol->NumberOfAuxSymbols * COFF::SymbolSize);
+      } else if (Symbol->isSectionDefinition()) {
+        // This symbol represents a section definition.
+        assert(Symbol->NumberOfAuxSymbols == 1 &&
+               "Expected a single aux symbol to describe this section!");
+
+        const object::coff_aux_section_definition *ObjSD =
+            reinterpret_cast<const object::coff_aux_section_definition *>(
+                AuxData.data());
+        dumpSectionDefinition(&Sym, ObjSD);
+      } else if (Symbol->isCLRToken()) {
+        // This symbol represents a CLR token definition.
+        assert(Symbol->NumberOfAuxSymbols == 1 &&
+               "Expected a single aux symbol to describe this CLR Token");
+
+        const object::coff_aux_clr_token *ObjCLRToken =
+            reinterpret_cast<const object::coff_aux_clr_token *>(
+                AuxData.data());
+        dumpCLRTokenDefinition(&Sym, ObjCLRToken);
+      } else {
+        llvm_unreachable("Unhandled auxiliary symbol!");
+      }
+    }
     Symbols.push_back(Sym);
   }
 }
index c757eb64fb72b8422057830b44a710161e631d86..a0ede246bd6813ba4bf9fd837fb3f429ea89c487 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "yaml2obj.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringSwitch.h"
@@ -153,13 +154,22 @@ static bool layoutCOFF(COFFParser &CP) {
   for (std::vector<COFFYAML::Symbol>::iterator i = CP.Obj.Symbols.begin(),
                                                e = CP.Obj.Symbols.end();
                                                i != e; ++i) {
-    unsigned AuxBytes = i->AuxiliaryData.binary_size();
-    if (AuxBytes % COFF::SymbolSize != 0) {
-      errs() << "AuxiliaryData size not a multiple of symbol size!\n";
-      return false;
-    }
-    i->Header.NumberOfAuxSymbols = AuxBytes / COFF::SymbolSize;
-    NumberOfSymbols += 1 + i->Header.NumberOfAuxSymbols;
+    uint32_t NumberOfAuxSymbols = 0;
+    if (i->FunctionDefinition)
+      NumberOfAuxSymbols += 1;
+    if (i->bfAndefSymbol)
+      NumberOfAuxSymbols += 1;
+    if (i->WeakExternal)
+      NumberOfAuxSymbols += 1;
+    if (!i->File.empty())
+      NumberOfAuxSymbols +=
+          (i->File.size() + COFF::SymbolSize - 1) / COFF::SymbolSize;
+    if (i->SectionDefinition)
+      NumberOfAuxSymbols += 1;
+    if (i->CLRToken)
+      NumberOfAuxSymbols += 1;
+    i->Header.NumberOfAuxSymbols = NumberOfAuxSymbols;
+    NumberOfSymbols += 1 + NumberOfAuxSymbols;
   }
 
   // Store all the allocated start addresses in the header.
@@ -194,6 +204,24 @@ binary_le_impl<value_type> binary_le(value_type V) {
   return binary_le_impl<value_type>(V);
 }
 
+template <size_t NumBytes>
+struct zeros_impl {
+  zeros_impl() {}
+};
+
+template <size_t NumBytes>
+raw_ostream &operator<<(raw_ostream &OS, const zeros_impl<NumBytes> &) {
+  char Buffer[NumBytes];
+  memset(Buffer, 0, sizeof(Buffer));
+  OS.write(Buffer, sizeof(Buffer));
+  return OS;
+}
+
+template <typename T>
+zeros_impl<sizeof(T)> zeros(const T &) {
+  return zeros_impl<sizeof(T)>();
+}
+
 bool writeCOFF(COFFParser &CP, raw_ostream &OS) {
   OS << binary_le(CP.Obj.Header.Machine)
      << binary_le(CP.Obj.Header.NumberOfSections)
@@ -253,7 +281,45 @@ bool writeCOFF(COFFParser &CP, raw_ostream &OS) {
        << binary_le(i->Header.Type)
        << binary_le(i->Header.StorageClass)
        << binary_le(i->Header.NumberOfAuxSymbols);
-    i->AuxiliaryData.writeAsBinary(OS);
+
+    if (i->FunctionDefinition)
+      OS << binary_le(i->FunctionDefinition->TagIndex)
+         << binary_le(i->FunctionDefinition->TotalSize)
+         << binary_le(i->FunctionDefinition->PointerToLinenumber)
+         << binary_le(i->FunctionDefinition->PointerToNextFunction)
+         << zeros(i->FunctionDefinition->unused);
+    if (i->bfAndefSymbol)
+      OS << zeros(i->bfAndefSymbol->unused1)
+         << binary_le(i->bfAndefSymbol->Linenumber)
+         << zeros(i->bfAndefSymbol->unused2)
+         << binary_le(i->bfAndefSymbol->PointerToNextFunction)
+         << zeros(i->bfAndefSymbol->unused3);
+    if (i->WeakExternal)
+      OS << binary_le(i->WeakExternal->TagIndex)
+         << binary_le(i->WeakExternal->Characteristics)
+         << zeros(i->WeakExternal->unused);
+    if (!i->File.empty()) {
+      uint32_t NumberOfAuxRecords =
+          (i->File.size() + COFF::SymbolSize - 1) / COFF::SymbolSize;
+      uint32_t NumberOfAuxBytes = NumberOfAuxRecords * COFF::SymbolSize;
+      uint32_t NumZeros = NumberOfAuxBytes - i->File.size();
+      OS.write(i->File.data(), i->File.size());
+      for (uint32_t Padding = 0; Padding < NumZeros; ++Padding)
+        OS.write(0);
+    }
+    if (i->SectionDefinition)
+      OS << binary_le(i->SectionDefinition->Length)
+         << binary_le(i->SectionDefinition->NumberOfRelocations)
+         << binary_le(i->SectionDefinition->NumberOfLinenumbers)
+         << binary_le(i->SectionDefinition->CheckSum)
+         << binary_le(i->SectionDefinition->Number)
+         << binary_le(i->SectionDefinition->Selection)
+         << zeros(i->SectionDefinition->unused);
+    if (i->CLRToken)
+      OS << binary_le(i->CLRToken->AuxType)
+         << zeros(i->CLRToken->unused1)
+         << binary_le(i->CLRToken->SymbolTableIndex)
+         << zeros(i->CLRToken->unused2);
   }
 
   // Output string table.