Object: Provide a richer means of describing auxiliary symbols

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
This commit is contained in:
David Majnemer 2014-03-19 04:47:47 +00:00
parent 92c5a193e0
commit 6d191534f6
14 changed files with 457 additions and 54 deletions

View File

@ -202,6 +202,37 @@ struct coff_symbol {
uint8_t getBaseType() const { return Type & 0x0F; } uint8_t getBaseType() const { return Type & 0x0F; }
uint8_t getComplexType() const { return (Type & 0xF0) >> 4; } 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 { struct coff_section {

View File

@ -14,6 +14,7 @@
#ifndef LLVM_OBJECT_COFFYAML_H #ifndef LLVM_OBJECT_COFFYAML_H
#define LLVM_OBJECT_COFFYAML_H #define LLVM_OBJECT_COFFYAML_H
#include "llvm/ADT/Optional.h"
#include "llvm/Object/YAML.h" #include "llvm/Object/YAML.h"
#include "llvm/Support/COFF.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 // 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. // to use yaml::IO, we use these structures which are closer to the source.
namespace COFFYAML { 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 { struct Relocation {
uint32_t VirtualAddress; uint32_t VirtualAddress;
uint16_t Type; uint16_t Type;
@ -54,7 +59,12 @@ namespace COFFYAML {
COFF::symbol Header; COFF::symbol Header;
COFF::SymbolBaseType SimpleType; COFF::SymbolBaseType SimpleType;
COFF::SymbolComplexType ComplexType; 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; StringRef Name;
Symbol(); Symbol();
}; };
@ -75,6 +85,21 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Relocation)
namespace llvm { namespace llvm {
namespace yaml { 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 <> template <>
struct ScalarEnumerationTraits<COFF::MachineTypes> { struct ScalarEnumerationTraits<COFF::MachineTypes> {
static void enumeration(IO &IO, COFF::MachineTypes &Value); static void enumeration(IO &IO, COFF::MachineTypes &Value);
@ -120,6 +145,26 @@ struct MappingTraits<COFF::header> {
static void mapping(IO &IO, COFF::header &H); 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 <> template <>
struct MappingTraits<COFFYAML::Symbol> { struct MappingTraits<COFFYAML::Symbol> {
static void mapping(IO &IO, COFFYAML::Symbol &S); static void mapping(IO &IO, COFFYAML::Symbol &S);

View File

@ -212,6 +212,10 @@ namespace COFF {
SCT_COMPLEX_TYPE_SHIFT = 4 SCT_COMPLEX_TYPE_SHIFT = 4
}; };
enum AuxSymbolType {
IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF = 1
};
struct section { struct section {
char Name[NameSize]; char Name[NameSize];
uint32_t VirtualSize; uint32_t VirtualSize;
@ -337,7 +341,7 @@ namespace COFF {
uint32_t TotalSize; uint32_t TotalSize;
uint32_t PointerToLinenumber; uint32_t PointerToLinenumber;
uint32_t PointerToNextFunction; uint32_t PointerToNextFunction;
uint8_t unused[2]; char unused[2];
}; };
struct AuxiliarybfAndefSymbol { struct AuxiliarybfAndefSymbol {
@ -372,7 +376,14 @@ namespace COFF {
uint32_t CheckSum; uint32_t CheckSum;
uint16_t Number; uint16_t Number;
uint8_t Selection; 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 { union Auxiliary {

View File

@ -13,6 +13,7 @@
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
@ -420,6 +421,11 @@ public:
this->processKey(Key, Val, false); 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> template <typename T>
typename std::enable_if<!has_SequenceTraits<T>::value,void>::type typename std::enable_if<!has_SequenceTraits<T>::value,void>::type
mapOptional(const char* Key, T& Val) { mapOptional(const char* Key, T& Val) {
@ -432,6 +438,26 @@ public:
} }
private: 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> template <typename T>
void processKeyWithDefault(const char *Key, T &Val, const T& DefaultValue, void processKeyWithDefault(const char *Key, T &Val, const T& DefaultValue,
bool Required) { bool Required) {

View File

@ -174,7 +174,7 @@ error_code COFFObjectFile::getSymbolType(DataRefImpl Ref,
if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) { Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) {
Result = SymbolRef::ST_Unknown; Result = SymbolRef::ST_Unknown;
} else if (Symb->getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION) { } else if (Symb->isFunctionDefinition()) {
Result = SymbolRef::ST_Function; Result = SymbolRef::ST_Function;
} else { } else {
uint32_t Characteristics = 0; uint32_t Characteristics = 0;

View File

@ -23,6 +23,31 @@ Object::Object() { memset(&Header, 0, sizeof(COFF::header)); }
} }
namespace yaml { 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( void ScalarEnumerationTraits<COFF::MachineTypes>::enumeration(
IO &IO, COFF::MachineTypes &Value) { IO &IO, COFF::MachineTypes &Value) {
ECase(IMAGE_FILE_MACHINE_UNKNOWN); ECase(IMAGE_FILE_MACHINE_UNKNOWN);
@ -187,6 +212,24 @@ void ScalarBitSetTraits<COFF::SectionCharacteristics>::bitset(
#undef BCase #undef BCase
namespace { 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 { struct NSectionCharacteristics {
NSectionCharacteristics(IO &) NSectionCharacteristics(IO &)
: Characteristics(COFF::SectionCharacteristics(0)) {} : Characteristics(COFF::SectionCharacteristics(0)) {}
@ -196,6 +239,15 @@ struct NSectionCharacteristics {
COFF::SectionCharacteristics Characteristics; 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 { struct NStorageClass {
NStorageClass(IO &) : StorageClass(COFF::SymbolStorageClass(0)) {} NStorageClass(IO &) : StorageClass(COFF::SymbolStorageClass(0)) {}
NStorageClass(IO &, uint8_t S) : StorageClass(COFF::SymbolStorageClass(S)) {} 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); 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) { void MappingTraits<COFFYAML::Symbol>::mapping(IO &IO, COFFYAML::Symbol &S) {
MappingNormalization<NStorageClass, uint8_t> NS(IO, S.Header.StorageClass); 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("SimpleType", S.SimpleType);
IO.mapRequired("ComplexType", S.ComplexType); IO.mapRequired("ComplexType", S.ComplexType);
IO.mapRequired("StorageClass", NS->StorageClass); IO.mapRequired("StorageClass", NS->StorageClass);
IO.mapOptional("NumberOfAuxSymbols", S.Header.NumberOfAuxSymbols, IO.mapOptional("FunctionDefinition", S.FunctionDefinition);
(uint8_t) 0); IO.mapOptional("bfAndefSymbol", S.bfAndefSymbol);
IO.mapOptional("AuxiliaryData", S.AuxiliaryData, object::yaml::BinaryRef()); 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) { void MappingTraits<COFFYAML::Section>::mapping(IO &IO, COFFYAML::Section &Sec) {

View File

@ -39,8 +39,12 @@ symbols:
SimpleType: IMAGE_SYM_TYPE_NULL # (0) SimpleType: IMAGE_SYM_TYPE_NULL # (0)
ComplexType: IMAGE_SYM_DTYPE_NULL # (0) ComplexType: IMAGE_SYM_DTYPE_NULL # (0)
StorageClass: IMAGE_SYM_CLASS_STATIC # (3) StorageClass: IMAGE_SYM_CLASS_STATIC # (3)
NumberOfAuxSymbols: 1 SectionDefinition:
AuxiliaryData: !hex "240000000300000000000000010000000000" # |$.................| Length: 36
NumberOfRelocations: 3
NumberOfLinenumbers: 0
CheckSum: 0
Number: 1
- !Symbol - !Symbol
Name: .data Name: .data
@ -49,8 +53,12 @@ symbols:
SimpleType: IMAGE_SYM_TYPE_NULL # (0) SimpleType: IMAGE_SYM_TYPE_NULL # (0)
ComplexType: IMAGE_SYM_DTYPE_NULL # (0) ComplexType: IMAGE_SYM_DTYPE_NULL # (0)
StorageClass: IMAGE_SYM_CLASS_STATIC # (3) StorageClass: IMAGE_SYM_CLASS_STATIC # (3)
NumberOfAuxSymbols: 1 SectionDefinition:
AuxiliaryData: !hex "0D0000000000000000000000020000000000" # |..................| Length: 13
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 0
Number: 2
- !Symbol - !Symbol
Name: _main Name: _main

View File

@ -38,8 +38,12 @@ symbols:
SimpleType: IMAGE_SYM_TYPE_NULL # (0) SimpleType: IMAGE_SYM_TYPE_NULL # (0)
ComplexType: IMAGE_SYM_DTYPE_NULL # (0) ComplexType: IMAGE_SYM_DTYPE_NULL # (0)
StorageClass: IMAGE_SYM_CLASS_STATIC # (3) StorageClass: IMAGE_SYM_CLASS_STATIC # (3)
NumberOfAuxSymbols: 1 SectionDefinition:
AuxiliaryData: !hex "260000000300000000000000010000000000" # |&.................| Length: 38
NumberOfRelocations: 3
NumberOfLinenumbers: 0
CheckSum: 0
Number: 1
- !Symbol - !Symbol
Name: .data Name: .data
@ -48,8 +52,12 @@ symbols:
SimpleType: IMAGE_SYM_TYPE_NULL # (0) SimpleType: IMAGE_SYM_TYPE_NULL # (0)
ComplexType: IMAGE_SYM_DTYPE_NULL # (0) ComplexType: IMAGE_SYM_DTYPE_NULL # (0)
StorageClass: IMAGE_SYM_CLASS_STATIC # (3) StorageClass: IMAGE_SYM_CLASS_STATIC # (3)
NumberOfAuxSymbols: 1 SectionDefinition:
AuxiliaryData: !hex "0D0000000000000000000000020000000000" # |..................| Length: 13
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 0
Number: 2
- !Symbol - !Symbol
Name: main Name: main

View File

@ -36,8 +36,12 @@ COFF-I386-NEXT: SectionNumber: 1
COFF-I386-NEXT: SimpleType: IMAGE_SYM_TYPE_NULL COFF-I386-NEXT: SimpleType: IMAGE_SYM_TYPE_NULL
COFF-I386-NEXT: ComplexType: IMAGE_SYM_DTYPE_NULL COFF-I386-NEXT: ComplexType: IMAGE_SYM_DTYPE_NULL
COFF-I386-NEXT: StorageClass: IMAGE_SYM_CLASS_STATIC COFF-I386-NEXT: StorageClass: IMAGE_SYM_CLASS_STATIC
COFF-I386-NEXT: NumberOfAuxSymbols: 1 COFF-I386-NEXT: SectionDefinition:
COFF-I386-NEXT: AuxiliaryData: 240000000300000000000000010000000000 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: - Name: .data
COFF-I386-NEXT: Value: 0 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: SimpleType: IMAGE_SYM_TYPE_NULL
COFF-I386-NEXT: ComplexType: IMAGE_SYM_DTYPE_NULL COFF-I386-NEXT: ComplexType: IMAGE_SYM_DTYPE_NULL
COFF-I386-NEXT: StorageClass: IMAGE_SYM_CLASS_STATIC COFF-I386-NEXT: StorageClass: IMAGE_SYM_CLASS_STATIC
COFF-I386-NEXT: NumberOfAuxSymbols: 1 COFF-I386-NEXT: SectionDefinition:
COFF-I386-NEXT: AuxiliaryData: 0D0000000000000000000000020000000000 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: - Name: _main
COFF-I386-NEXT: Value: 0 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: SimpleType: IMAGE_SYM_TYPE_NULL
COFF-X86-64-NEXT: ComplexType: IMAGE_SYM_DTYPE_NULL COFF-X86-64-NEXT: ComplexType: IMAGE_SYM_DTYPE_NULL
COFF-X86-64-NEXT: StorageClass: IMAGE_SYM_CLASS_STATIC COFF-X86-64-NEXT: StorageClass: IMAGE_SYM_CLASS_STATIC
COFF-X86-64-NEXT: NumberOfAuxSymbols: 1 COFF-X86-64-NEXT: SectionDefinition:
COFF-X86-64-NEXT: AuxiliaryData: 260000000300000000000000010000000000 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: - Name: .data
COFF-X86-64-NEXT: Value: 0 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: SimpleType: IMAGE_SYM_TYPE_NULL
COFF-X86-64-NEXT: ComplexType: IMAGE_SYM_DTYPE_NULL COFF-X86-64-NEXT: ComplexType: IMAGE_SYM_DTYPE_NULL
COFF-X86-64-NEXT: StorageClass: IMAGE_SYM_CLASS_STATIC COFF-X86-64-NEXT: StorageClass: IMAGE_SYM_CLASS_STATIC
COFF-X86-64-NEXT: NumberOfAuxSymbols: 1 COFF-X86-64-NEXT: SectionDefinition:
COFF-X86-64-NEXT: AuxiliaryData: 0D0000000000000000000000020000000000 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: - Name: main
COFF-X86-64-NEXT: Value: 0 COFF-X86-64-NEXT: Value: 0

View File

@ -344,8 +344,7 @@ static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) {
return 'i'; return 'i';
// Check for section symbol. // Check for section symbol.
else if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC && else if (Symb->isSectionDefinition())
Symb->Value == 0)
return 's'; return 's';
} }

View File

@ -663,8 +663,7 @@ static void PrintCOFFSymbolTable(const COFFObjectFile *coff) {
for (int i = 0, e = header->NumberOfSymbols; i != e; ++i) { for (int i = 0, e = header->NumberOfSymbols; i != e; ++i) {
if (aux_count--) { if (aux_count--) {
// Figure out which type of aux this is. // Figure out which type of aux this is.
if (symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC if (symbol->isSectionDefinition()) { // Section definition.
&& symbol->Value == 0) { // Section definition.
const coff_aux_section_definition *asd; const coff_aux_section_definition *asd;
if (error(coff->getAuxSymbol<coff_aux_section_definition>(i, asd))) if (error(coff->getAuxSymbol<coff_aux_section_definition>(i, asd)))
return; return;

View File

@ -946,12 +946,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) {
W.printNumber("AuxSymbolCount", Symbol->NumberOfAuxSymbols); W.printNumber("AuxSymbolCount", Symbol->NumberOfAuxSymbols);
for (unsigned I = 0; I < Symbol->NumberOfAuxSymbols; ++I) { for (unsigned I = 0; I < Symbol->NumberOfAuxSymbols; ++I) {
if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && if (Symbol->isFunctionDefinition()) {
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) {
const coff_aux_function_definition *Aux; const coff_aux_function_definition *Aux;
if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
break; break;
@ -963,11 +958,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) {
W.printHex("PointerToNextFunction", Aux->PointerToNextFunction); W.printHex("PointerToNextFunction", Aux->PointerToNextFunction);
W.printBinary("Unused", makeArrayRef(Aux->Unused)); W.printBinary("Unused", makeArrayRef(Aux->Unused));
} else if ( } else if (Symbol->isWeakExternal()) {
Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL ||
(Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
Symbol->SectionNumber == COFF::IMAGE_SYM_UNDEFINED &&
Symbol->Value == 0)) {
const coff_aux_weak_external *Aux; const coff_aux_weak_external *Aux;
if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
break; break;
@ -987,7 +978,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) {
makeArrayRef(WeakExternalCharacteristics)); makeArrayRef(WeakExternalCharacteristics));
W.printBinary("Unused", makeArrayRef(Aux->Unused)); 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; const coff_aux_file_record *Aux;
if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
break; break;
@ -995,11 +986,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) {
DictScope AS(W, "AuxFileRecord"); DictScope AS(W, "AuxFileRecord");
W.printString("FileName", StringRef(Aux->FileName)); W.printString("FileName", StringRef(Aux->FileName));
// C++/CLI creates external ABS symbols for non-const appdomain globals. } else if (Symbol->isSectionDefinition()) {
// 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)) {
const coff_aux_section_definition *Aux; const coff_aux_section_definition *Aux;
if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
break; break;
@ -1026,7 +1013,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) {
W.printNumber("AssocSection", AssocName, Aux->Number); 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; const coff_aux_clr_token *Aux;
if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
break; break;

View 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) { void COFFDumper::dumpSymbols(unsigned NumSymbols) {
std::vector<COFFYAML::Symbol> &Symbols = YAMLObj.Symbols; std::vector<COFFYAML::Symbol> &Symbols = YAMLObj.Symbols;
for (const auto &S : Obj.symbols()) { for (const auto &S : Obj.symbols()) {
@ -90,7 +145,62 @@ void COFFDumper::dumpSymbols(unsigned NumSymbols) {
Sym.Header.Value = Symbol->Value; Sym.Header.Value = Symbol->Value;
Sym.Header.SectionNumber = Symbol->SectionNumber; Sym.Header.SectionNumber = Symbol->SectionNumber;
Sym.Header.NumberOfAuxSymbols = Symbol->NumberOfAuxSymbols; 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); Symbols.push_back(Sym);
} }
} }

View File

@ -14,6 +14,7 @@
#include "yaml2obj.h" #include "yaml2obj.h"
#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallString.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSwitch.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(), for (std::vector<COFFYAML::Symbol>::iterator i = CP.Obj.Symbols.begin(),
e = CP.Obj.Symbols.end(); e = CP.Obj.Symbols.end();
i != e; ++i) { i != e; ++i) {
unsigned AuxBytes = i->AuxiliaryData.binary_size(); uint32_t NumberOfAuxSymbols = 0;
if (AuxBytes % COFF::SymbolSize != 0) { if (i->FunctionDefinition)
errs() << "AuxiliaryData size not a multiple of symbol size!\n"; NumberOfAuxSymbols += 1;
return false; if (i->bfAndefSymbol)
} NumberOfAuxSymbols += 1;
i->Header.NumberOfAuxSymbols = AuxBytes / COFF::SymbolSize; if (i->WeakExternal)
NumberOfSymbols += 1 + i->Header.NumberOfAuxSymbols; 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. // 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); 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) { bool writeCOFF(COFFParser &CP, raw_ostream &OS) {
OS << binary_le(CP.Obj.Header.Machine) OS << binary_le(CP.Obj.Header.Machine)
<< binary_le(CP.Obj.Header.NumberOfSections) << 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.Type)
<< binary_le(i->Header.StorageClass) << binary_le(i->Header.StorageClass)
<< binary_le(i->Header.NumberOfAuxSymbols); << 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. // Output string table.