Skip to content

Commit

Permalink
Object: Provide a richer means of describing auxiliary symbols
Browse files Browse the repository at this point in the history
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
  • Loading branch information
majnemer committed Mar 19, 2014
1 parent 92c5a19 commit 6d19153
Show file tree
Hide file tree
Showing 14 changed files with 457 additions and 54 deletions.
31 changes: 31 additions & 0 deletions include/llvm/Object/COFF.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
47 changes: 46 additions & 1 deletion include/llvm/Object/COFFYAML.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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;
Expand All @@ -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();
};
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
15 changes: 13 additions & 2 deletions include/llvm/Support/COFF.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -337,7 +341,7 @@ namespace COFF {
uint32_t TotalSize;
uint32_t PointerToLinenumber;
uint32_t PointerToNextFunction;
uint8_t unused[2];
char unused[2];
};

struct AuxiliarybfAndefSymbol {
Expand Down Expand Up @@ -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 {
Expand Down
26 changes: 26 additions & 0 deletions include/llvm/Support/YAMLTraits.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -420,6 +421,11 @@ class IO {
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) {
Expand All @@ -432,6 +438,26 @@ class IO {
}

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) {
Expand Down
2 changes: 1 addition & 1 deletion lib/Object/COFFObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
103 changes: 100 additions & 3 deletions lib/Object/COFFYAML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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)) {}
Expand All @@ -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)) {}
Expand Down Expand Up @@ -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);

Expand All @@ -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) {
Expand Down
16 changes: 12 additions & 4 deletions test/Object/Inputs/COFF/i386.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
Loading

0 comments on commit 6d19153

Please sign in to comment.