llvm.org GIT mirror llvm / 6d19153
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 David Majnemer 5 years ago
14 changed file(s) with 457 addition(s) and 54 deletion(s). Raw diff Collapse all Expand all
201201 uint8_t getBaseType() const { return Type & 0x0F; }
202202
203203 uint8_t getComplexType() const { return (Type & 0xF0) >> 4; }
204
205 bool isFunctionDefinition() const {
206 return StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
207 getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
208 getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION &&
209 COFF::isReservedSectionNumber(SectionNumber);
210 }
211
212 bool isWeakExternal() const {
213 return StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL ||
214 (StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
215 SectionNumber == COFF::IMAGE_SYM_UNDEFINED && Value == 0);
216 }
217
218 bool isFileRecord() const {
219 return StorageClass == COFF::IMAGE_SYM_CLASS_FILE;
220 }
221
222 bool isSectionDefinition() const {
223 // C++/CLI creates external ABS symbols for non-const appdomain globals.
224 // These are also followed by an auxiliary section definition.
225 bool isAppdomainGlobal = StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
226 SectionNumber == COFF::IMAGE_SYM_ABSOLUTE;
227 bool isOrdinarySection =
228 StorageClass == COFF::IMAGE_SYM_CLASS_STATIC && Value == 0;
229 return isAppdomainGlobal || isOrdinarySection;
230 }
231
232 bool isCLRToken() const {
233 return StorageClass == COFF::IMAGE_SYM_CLASS_CLR_TOKEN;
234 }
204235 };
205236
206237 struct coff_section {
1313 #ifndef LLVM_OBJECT_COFFYAML_H
1414 #define LLVM_OBJECT_COFFYAML_H
1515
16 #include "llvm/ADT/Optional.h"
1617 #include "llvm/Object/YAML.h"
1718 #include "llvm/Support/COFF.h"
1819
3435 // The structure of the yaml files is not an exact 1:1 match to COFF. In order
3536 // to use yaml::IO, we use these structures which are closer to the source.
3637 namespace COFFYAML {
38 LLVM_YAML_STRONG_TYPEDEF(uint8_t, COMDATType)
39 LLVM_YAML_STRONG_TYPEDEF(uint32_t, WeakExternalCharacteristics)
40 LLVM_YAML_STRONG_TYPEDEF(uint8_t, AuxSymbolType)
41
3742 struct Relocation {
3843 uint32_t VirtualAddress;
3944 uint16_t Type;
5358 COFF::symbol Header;
5459 COFF::SymbolBaseType SimpleType;
5560 COFF::SymbolComplexType ComplexType;
56 object::yaml::BinaryRef AuxiliaryData;
61 Optional FunctionDefinition;
62 Optional bfAndefSymbol;
63 Optional WeakExternal;
64 StringRef File;
65 Optional SectionDefinition;
66 Optional CLRToken;
5767 StringRef Name;
5868 Symbol();
5969 };
7383
7484 namespace llvm {
7585 namespace yaml {
86
87 template <>
88 struct ScalarEnumerationTraits {
89 static void enumeration(IO &IO, COFFYAML::WeakExternalCharacteristics &Value);
90 };
91
92 template <>
93 struct ScalarEnumerationTraits {
94 static void enumeration(IO &IO, COFFYAML::AuxSymbolType &Value);
95 };
96
97 template <>
98 struct ScalarEnumerationTraits {
99 static void enumeration(IO &IO, COFFYAML::COMDATType &Value);
100 };
76101
77102 template <>
78103 struct ScalarEnumerationTraits {
119144 static void mapping(IO &IO, COFF::header &H);
120145 };
121146
147 template <> struct MappingTraits {
148 static void mapping(IO &IO, COFF::AuxiliaryFunctionDefinition &AFD);
149 };
150
151 template <> struct MappingTraits {
152 static void mapping(IO &IO, COFF::AuxiliarybfAndefSymbol &AAS);
153 };
154
155 template <> struct MappingTraits {
156 static void mapping(IO &IO, COFF::AuxiliaryWeakExternal &AWE);
157 };
158
159 template <> struct MappingTraits {
160 static void mapping(IO &IO, COFF::AuxiliarySectionDefinition &ASD);
161 };
162
163 template <> struct MappingTraits {
164 static void mapping(IO &IO, COFF::AuxiliaryCLRToken &ACT);
165 };
166
122167 template <>
123168 struct MappingTraits {
124169 static void mapping(IO &IO, COFFYAML::Symbol &S);
211211 SCT_COMPLEX_TYPE_SHIFT = 4
212212 };
213213
214 enum AuxSymbolType {
215 IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF = 1
216 };
217
214218 struct section {
215219 char Name[NameSize];
216220 uint32_t VirtualSize;
336340 uint32_t TotalSize;
337341 uint32_t PointerToLinenumber;
338342 uint32_t PointerToNextFunction;
339 uint8_t unused[2];
343 char unused[2];
340344 };
341345
342346 struct AuxiliarybfAndefSymbol {
371375 uint32_t CheckSum;
372376 uint16_t Number;
373377 uint8_t Selection;
374 uint8_t unused[3];
378 char unused[3];
379 };
380
381 struct AuxiliaryCLRToken {
382 uint8_t AuxType;
383 uint8_t unused1;
384 uint32_t SymbolTableIndex;
385 char unused2[12];
375386 };
376387
377388 union Auxiliary {
1212
1313 #include "llvm/ADT/DenseMap.h"
1414 #include "llvm/ADT/DenseMapInfo.h"
15 #include "llvm/ADT/Optional.h"
1516 #include "llvm/ADT/SmallVector.h"
1617 #include "llvm/ADT/StringMap.h"
1718 #include "llvm/ADT/StringRef.h"
420421 }
421422
422423 template
424 void mapOptional(const char* Key, Optional &Val) {
425 processKeyWithDefault(Key, Val, Optional(), /*Required=*/false);
426 }
427
428 template
423429 typename std::enable_if::value,void>::type
424430 mapOptional(const char* Key, T& Val) {
425431 this->processKey(Key, Val, false);
431437 }
432438
433439 private:
440 template
441 void processKeyWithDefault(const char *Key, Optional &Val,
442 const Optional &DefaultValue, bool Required) {
443 assert(DefaultValue.hasValue() == false &&
444 "Optional shouldn't have a value!");
445 void *SaveInfo;
446 bool UseDefault;
447 const bool sameAsDefault = outputting() && !Val.hasValue();
448 if (!outputting() && !Val.hasValue())
449 Val = T();
450 if (this->preflightKey(Key, Required, sameAsDefault, UseDefault,
451 SaveInfo)) {
452 yamlize(*this, Val.getValue(), Required);
453 this->postflightKey(SaveInfo);
454 } else {
455 if (UseDefault)
456 Val = DefaultValue;
457 }
458 }
459
434460 template
435461 void processKeyWithDefault(const char *Key, T &Val, const T& DefaultValue,
436462 bool Required) {
173173 if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
174174 Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) {
175175 Result = SymbolRef::ST_Unknown;
176 } else if (Symb->getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION) {
176 } else if (Symb->isFunctionDefinition()) {
177177 Result = SymbolRef::ST_Function;
178178 } else {
179179 uint32_t Characteristics = 0;
2222 }
2323
2424 namespace yaml {
25 void ScalarEnumerationTraits::enumeration(
26 IO &IO, COFFYAML::COMDATType &Value) {
27 IO.enumCase(Value, "0", 0);
28 ECase(IMAGE_COMDAT_SELECT_NODUPLICATES);
29 ECase(IMAGE_COMDAT_SELECT_ANY);
30 ECase(IMAGE_COMDAT_SELECT_SAME_SIZE);
31 ECase(IMAGE_COMDAT_SELECT_EXACT_MATCH);
32 ECase(IMAGE_COMDAT_SELECT_ASSOCIATIVE);
33 ECase(IMAGE_COMDAT_SELECT_LARGEST);
34 ECase(IMAGE_COMDAT_SELECT_NEWEST);
35 }
36
37 void
38 ScalarEnumerationTraits::enumeration(
39 IO &IO, COFFYAML::WeakExternalCharacteristics &Value) {
40 ECase(IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
41 ECase(IMAGE_WEAK_EXTERN_SEARCH_LIBRARY);
42 ECase(IMAGE_WEAK_EXTERN_SEARCH_ALIAS);
43 }
44
45 void ScalarEnumerationTraits::enumeration(
46 IO &IO, COFFYAML::AuxSymbolType &Value) {
47 ECase(IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF);
48 }
49
2550 void ScalarEnumerationTraits::enumeration(
2651 IO &IO, COFF::MachineTypes &Value) {
2752 ECase(IMAGE_FILE_MACHINE_UNKNOWN);
186211 #undef BCase
187212
188213 namespace {
214 struct NSectionSelectionType {
215 NSectionSelectionType(IO &)
216 : SelectionType(COFFYAML::COMDATType(0)) {}
217 NSectionSelectionType(IO &, uint8_t C)
218 : SelectionType(COFFYAML::COMDATType(C)) {}
219 uint8_t denormalize(IO &) { return SelectionType; }
220 COFFYAML::COMDATType SelectionType;
221 };
222
223 struct NWeakExternalCharacteristics {
224 NWeakExternalCharacteristics(IO &)
225 : Characteristics(COFFYAML::WeakExternalCharacteristics(0)) {}
226 NWeakExternalCharacteristics(IO &, uint32_t C)
227 : Characteristics(COFFYAML::WeakExternalCharacteristics(C)) {}
228 uint32_t denormalize(IO &) { return Characteristics; }
229 COFFYAML::WeakExternalCharacteristics Characteristics;
230 };
231
189232 struct NSectionCharacteristics {
190233 NSectionCharacteristics(IO &)
191234 : Characteristics(COFF::SectionCharacteristics(0)) {}
195238 COFF::SectionCharacteristics Characteristics;
196239 };
197240
241 struct NAuxTokenType {
242 NAuxTokenType(IO &)
243 : AuxType(COFFYAML::AuxSymbolType(0)) {}
244 NAuxTokenType(IO &, uint8_t C)
245 : AuxType(COFFYAML::AuxSymbolType(C)) {}
246 uint32_t denormalize(IO &) { return AuxType; }
247 COFFYAML::AuxSymbolType AuxType;
248 };
249
198250 struct NStorageClass {
199251 NStorageClass(IO &) : StorageClass(COFF::SymbolStorageClass(0)) {}
200252 NStorageClass(IO &, uint8_t S) : StorageClass(COFF::SymbolStorageClass(S)) {}
244296
245297 IO.mapRequired("Machine", NM->Machine);
246298 IO.mapOptional("Characteristics", NC->Characteristics);
299 }
300
301 void MappingTraits::mapping(
302 IO &IO, COFF::AuxiliaryFunctionDefinition &AFD) {
303 IO.mapRequired("TagIndex", AFD.TagIndex);
304 IO.mapRequired("TotalSize", AFD.TotalSize);
305 IO.mapRequired("PointerToLinenumber", AFD.PointerToLinenumber);
306 IO.mapRequired("PointerToNextFunction", AFD.PointerToNextFunction);
307 }
308
309 void MappingTraits::mapping(
310 IO &IO, COFF::AuxiliarybfAndefSymbol &AAS) {
311 IO.mapRequired("Linenumber", AAS.Linenumber);
312 IO.mapRequired("PointerToNextFunction", AAS.PointerToNextFunction);
313 }
314
315 void MappingTraits::mapping(
316 IO &IO, COFF::AuxiliaryWeakExternal &AWE) {
317 MappingNormalization NWEC(
318 IO, AWE.Characteristics);
319 IO.mapRequired("TagIndex", AWE.TagIndex);
320 IO.mapRequired("Characteristics", NWEC->Characteristics);
321 }
322
323 void MappingTraits::mapping(
324 IO &IO, COFF::AuxiliarySectionDefinition &ASD) {
325 MappingNormalization NSST(
326 IO, ASD.Selection);
327
328 IO.mapRequired("Length", ASD.Length);
329 IO.mapRequired("NumberOfRelocations", ASD.NumberOfRelocations);
330 IO.mapRequired("NumberOfLinenumbers", ASD.NumberOfLinenumbers);
331 IO.mapRequired("CheckSum", ASD.CheckSum);
332 IO.mapRequired("Number", ASD.Number);
333 IO.mapOptional("Selection", NSST->SelectionType, COFFYAML::COMDATType(0));
334 }
335
336 void MappingTraits::mapping(
337 IO &IO, COFF::AuxiliaryCLRToken &ACT) {
338 MappingNormalization NATT(IO, ACT.AuxType);
339 IO.mapRequired("AuxType", NATT->AuxType);
340 IO.mapRequired("SymbolTableIndex", ACT.SymbolTableIndex);
247341 }
248342
249343 void MappingTraits::mapping(IO &IO, COFFYAML::Symbol &S) {
255349 IO.mapRequired("SimpleType", S.SimpleType);
256350 IO.mapRequired("ComplexType", S.ComplexType);
257351 IO.mapRequired("StorageClass", NS->StorageClass);
258 IO.mapOptional("NumberOfAuxSymbols", S.Header.NumberOfAuxSymbols,
259 (uint8_t) 0);
260 IO.mapOptional("AuxiliaryData", S.AuxiliaryData, object::yaml::BinaryRef());
352 IO.mapOptional("FunctionDefinition", S.FunctionDefinition);
353 IO.mapOptional("bfAndefSymbol", S.bfAndefSymbol);
354 IO.mapOptional("WeakExternal", S.WeakExternal);
355 IO.mapOptional("File", S.File, StringRef());
356 IO.mapOptional("SectionDefinition", S.SectionDefinition);
357 IO.mapOptional("CLRToken", S.CLRToken);
261358 }
262359
263360 void MappingTraits::mapping(IO &IO, COFFYAML::Section &Sec) {
3838 SimpleType: IMAGE_SYM_TYPE_NULL # (0)
3939 ComplexType: IMAGE_SYM_DTYPE_NULL # (0)
4040 StorageClass: IMAGE_SYM_CLASS_STATIC # (3)
41 NumberOfAuxSymbols: 1
42 AuxiliaryData: !hex "240000000300000000000000010000000000" # |$.................|
41 SectionDefinition:
42 Length: 36
43 NumberOfRelocations: 3
44 NumberOfLinenumbers: 0
45 CheckSum: 0
46 Number: 1
4347
4448 - !Symbol
4549 Name: .data
4852 SimpleType: IMAGE_SYM_TYPE_NULL # (0)
4953 ComplexType: IMAGE_SYM_DTYPE_NULL # (0)
5054 StorageClass: IMAGE_SYM_CLASS_STATIC # (3)
51 NumberOfAuxSymbols: 1
52 AuxiliaryData: !hex "0D0000000000000000000000020000000000" # |..................|
55 SectionDefinition:
56 Length: 13
57 NumberOfRelocations: 0
58 NumberOfLinenumbers: 0
59 CheckSum: 0
60 Number: 2
5361
5462 - !Symbol
5563 Name: _main
3737 SimpleType: IMAGE_SYM_TYPE_NULL # (0)
3838 ComplexType: IMAGE_SYM_DTYPE_NULL # (0)
3939 StorageClass: IMAGE_SYM_CLASS_STATIC # (3)
40 NumberOfAuxSymbols: 1
41 AuxiliaryData: !hex "260000000300000000000000010000000000" # |&.................|
40 SectionDefinition:
41 Length: 38
42 NumberOfRelocations: 3
43 NumberOfLinenumbers: 0
44 CheckSum: 0
45 Number: 1
4246
4347 - !Symbol
4448 Name: .data
4751 SimpleType: IMAGE_SYM_TYPE_NULL # (0)
4852 ComplexType: IMAGE_SYM_DTYPE_NULL # (0)
4953 StorageClass: IMAGE_SYM_CLASS_STATIC # (3)
50 NumberOfAuxSymbols: 1
51 AuxiliaryData: !hex "0D0000000000000000000000020000000000" # |..................|
54 SectionDefinition:
55 Length: 13
56 NumberOfRelocations: 0
57 NumberOfLinenumbers: 0
58 CheckSum: 0
59 Number: 2
5260
5361 - !Symbol
5462 Name: main
3535 COFF-I386-NEXT: SimpleType: IMAGE_SYM_TYPE_NULL
3636 COFF-I386-NEXT: ComplexType: IMAGE_SYM_DTYPE_NULL
3737 COFF-I386-NEXT: StorageClass: IMAGE_SYM_CLASS_STATIC
38 COFF-I386-NEXT: NumberOfAuxSymbols: 1
39 COFF-I386-NEXT: AuxiliaryData: 240000000300000000000000010000000000
38 COFF-I386-NEXT: SectionDefinition:
39 COFF-I386-NEXT: Length: 36
40 COFF-I386-NEXT: NumberOfRelocations: 3
41 COFF-I386-NEXT: NumberOfLinenumbers: 0
42 COFF-I386-NEXT: CheckSum: 0
43 COFF-I386-NEXT: Number: 1
4044
4145 COFF-I386: - Name: .data
4246 COFF-I386-NEXT: Value: 0
4448 COFF-I386-NEXT: SimpleType: IMAGE_SYM_TYPE_NULL
4549 COFF-I386-NEXT: ComplexType: IMAGE_SYM_DTYPE_NULL
4650 COFF-I386-NEXT: StorageClass: IMAGE_SYM_CLASS_STATIC
47 COFF-I386-NEXT: NumberOfAuxSymbols: 1
48 COFF-I386-NEXT: AuxiliaryData: 0D0000000000000000000000020000000000
51 COFF-I386-NEXT: SectionDefinition:
52 COFF-I386-NEXT: Length: 13
53 COFF-I386-NEXT: NumberOfRelocations: 0
54 COFF-I386-NEXT: NumberOfLinenumbers: 0
55 COFF-I386-NEXT: CheckSum: 0
56 COFF-I386-NEXT: Number: 2
4957
5058 COFF-I386: - Name: _main
5159 COFF-I386-NEXT: Value: 0
110118 COFF-X86-64-NEXT: SimpleType: IMAGE_SYM_TYPE_NULL
111119 COFF-X86-64-NEXT: ComplexType: IMAGE_SYM_DTYPE_NULL
112120 COFF-X86-64-NEXT: StorageClass: IMAGE_SYM_CLASS_STATIC
113 COFF-X86-64-NEXT: NumberOfAuxSymbols: 1
114 COFF-X86-64-NEXT: AuxiliaryData: 260000000300000000000000010000000000
121 COFF-X86-64-NEXT: SectionDefinition:
122 COFF-X86-64-NEXT: Length: 38
123 COFF-X86-64-NEXT: NumberOfRelocations: 3
124 COFF-X86-64-NEXT: NumberOfLinenumbers: 0
125 COFF-X86-64-NEXT: CheckSum: 0
126 COFF-X86-64-NEXT: Number: 1
115127
116128 COFF-X86-64: - Name: .data
117129 COFF-X86-64-NEXT: Value: 0
119131 COFF-X86-64-NEXT: SimpleType: IMAGE_SYM_TYPE_NULL
120132 COFF-X86-64-NEXT: ComplexType: IMAGE_SYM_DTYPE_NULL
121133 COFF-X86-64-NEXT: StorageClass: IMAGE_SYM_CLASS_STATIC
122 COFF-X86-64-NEXT: NumberOfAuxSymbols: 1
123 COFF-X86-64-NEXT: AuxiliaryData: 0D0000000000000000000000020000000000
134 COFF-X86-64-NEXT: SectionDefinition:
135 COFF-X86-64-NEXT: Length: 13
136 COFF-X86-64-NEXT: NumberOfRelocations: 0
137 COFF-X86-64-NEXT: NumberOfLinenumbers: 0
138 COFF-X86-64-NEXT: CheckSum: 0
139 COFF-X86-64-NEXT: Number: 2
124140
125141 COFF-X86-64: - Name: main
126142 COFF-X86-64-NEXT: Value: 0
343343 return 'i';
344344
345345 // Check for section symbol.
346 else if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC &&
347 Symb->Value == 0)
346 else if (Symb->isSectionDefinition())
348347 return 's';
349348 }
350349
662662 for (int i = 0, e = header->NumberOfSymbols; i != e; ++i) {
663663 if (aux_count--) {
664664 // Figure out which type of aux this is.
665 if (symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC
666 && symbol->Value == 0) { // Section definition.
665 if (symbol->isSectionDefinition()) { // Section definition.
667666 const coff_aux_section_definition *asd;
668667 if (error(coff->getAuxSymbol(i, asd)))
669668 return;
945945 W.printNumber("AuxSymbolCount", Symbol->NumberOfAuxSymbols);
946946
947947 for (unsigned I = 0; I < Symbol->NumberOfAuxSymbols; ++I) {
948 if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
949 Symbol->getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
950 Symbol->getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION &&
951 Symbol->SectionNumber != COFF::IMAGE_SYM_DEBUG &&
952 Symbol->SectionNumber != COFF::IMAGE_SYM_ABSOLUTE &&
953 Symbol->SectionNumber != COFF::IMAGE_SYM_UNDEFINED) {
948 if (Symbol->isFunctionDefinition()) {
954949 const coff_aux_function_definition *Aux;
955950 if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
956951 break;
962957 W.printHex("PointerToNextFunction", Aux->PointerToNextFunction);
963958 W.printBinary("Unused", makeArrayRef(Aux->Unused));
964959
965 } else if (
966 Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL ||
967 (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
968 Symbol->SectionNumber == COFF::IMAGE_SYM_UNDEFINED &&
969 Symbol->Value == 0)) {
960 } else if (Symbol->isWeakExternal()) {
970961 const coff_aux_weak_external *Aux;
971962 if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
972963 break;
986977 makeArrayRef(WeakExternalCharacteristics));
987978 W.printBinary("Unused", makeArrayRef(Aux->Unused));
988979
989 } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_FILE) {
980 } else if (Symbol->isFileRecord()) {
990981 const coff_aux_file_record *Aux;
991982 if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
992983 break;
994985 DictScope AS(W, "AuxFileRecord");
995986 W.printString("FileName", StringRef(Aux->FileName));
996987
997 // C++/CLI creates external ABS symbols for non-const appdomain globals.
998 // These are also followed by an auxiliary section definition.
999 } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC ||
1000 (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
1001 Symbol->SectionNumber == COFF::IMAGE_SYM_ABSOLUTE)) {
988 } else if (Symbol->isSectionDefinition()) {
1002989 const coff_aux_section_definition *Aux;
1003990 if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
1004991 break;
10251012
10261013 W.printNumber("AssocSection", AssocName, Aux->Number);
10271014 }
1028 } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_CLR_TOKEN) {
1015 } else if (Symbol->isCLRToken()) {
10291016 const coff_aux_clr_token *Aux;
10301017 if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
10311018 break;
7777 }
7878 }
7979
80 static void
81 dumpFunctionDefinition(COFFYAML::Symbol *Sym,
82 const object::coff_aux_function_definition *ObjFD) {
83 COFF::AuxiliaryFunctionDefinition YAMLFD;
84 YAMLFD.TagIndex = ObjFD->TagIndex;
85 YAMLFD.TotalSize = ObjFD->TotalSize;
86 YAMLFD.PointerToLinenumber = ObjFD->PointerToLinenumber;
87 YAMLFD.PointerToNextFunction = ObjFD->PointerToNextFunction;
88
89 Sym->FunctionDefinition = YAMLFD;
90 }
91
92 static void
93 dumpbfAndEfLineInfo(COFFYAML::Symbol *Sym,
94 const object::coff_aux_bf_and_ef_symbol *ObjBES) {
95 COFF::AuxiliarybfAndefSymbol YAMLAAS;
96 YAMLAAS.Linenumber = ObjBES->Linenumber;
97 YAMLAAS.PointerToNextFunction = ObjBES->PointerToNextFunction;
98
99 Sym->bfAndefSymbol = YAMLAAS;
100 }
101
102 static void dumpWeakExternal(COFFYAML::Symbol *Sym,
103 const object::coff_aux_weak_external *ObjWE) {
104 COFF::AuxiliaryWeakExternal YAMLWE;
105 YAMLWE.TagIndex = ObjWE->TagIndex;
106 YAMLWE.Characteristics = ObjWE->Characteristics;
107
108 Sym->WeakExternal = YAMLWE;
109 }
110
111 static void
112 dumpSectionDefinition(COFFYAML::Symbol *Sym,
113 const object::coff_aux_section_definition *ObjSD) {
114 COFF::AuxiliarySectionDefinition YAMLASD;
115 YAMLASD.Length = ObjSD->Length;
116 YAMLASD.NumberOfRelocations = ObjSD->NumberOfRelocations;
117 YAMLASD.NumberOfLinenumbers = ObjSD->NumberOfLinenumbers;
118 YAMLASD.CheckSum = ObjSD->CheckSum;
119 YAMLASD.Number = ObjSD->Number;
120 YAMLASD.Selection = ObjSD->Selection;
121
122 Sym->SectionDefinition = YAMLASD;
123 }
124
125 static void
126 dumpCLRTokenDefinition(COFFYAML::Symbol *Sym,
127 const object::coff_aux_clr_token *ObjCLRToken) {
128 COFF::AuxiliaryCLRToken YAMLCLRToken;
129 YAMLCLRToken.AuxType = ObjCLRToken->AuxType;
130 YAMLCLRToken.SymbolTableIndex = ObjCLRToken->SymbolTableIndex;
131
132 Sym->CLRToken = YAMLCLRToken;
133 }
134
80135 void COFFDumper::dumpSymbols(unsigned NumSymbols) {
81136 std::vector &Symbols = YAMLObj.Symbols;
82137 for (const auto &S : Obj.symbols()) {
89144 Sym.Header.Value = Symbol->Value;
90145 Sym.Header.SectionNumber = Symbol->SectionNumber;
91146 Sym.Header.NumberOfAuxSymbols = Symbol->NumberOfAuxSymbols;
92 Sym.AuxiliaryData = object::yaml::BinaryRef(Obj.getSymbolAuxData(Symbol));
147
148 if (Symbol->NumberOfAuxSymbols > 0) {
149 ArrayRef AuxData = Obj.getSymbolAuxData(Symbol);
150 if (Symbol->isFunctionDefinition()) {
151 // This symbol represents a function definition.
152 assert(Symbol->NumberOfAuxSymbols == 1 &&
153 "Expected a single aux symbol to describe this function!");
154
155 const object::coff_aux_function_definition *ObjFD =
156 reinterpret_cast(
157 AuxData.data());
158 dumpFunctionDefinition(&Sym, ObjFD);
159 } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_FUNCTION) {
160 // This symbol describes function line number information.
161 assert(Symbol->NumberOfAuxSymbols == 1 &&
162 "Exepected a single aux symbol to describe this section!");
163
164 const object::coff_aux_bf_and_ef_symbol *ObjBES =
165 reinterpret_cast(
166 AuxData.data());
167 dumpbfAndEfLineInfo(&Sym, ObjBES);
168 } else if (Symbol->isWeakExternal()) {
169 // This symbol represents a weak external definition.
170 assert(Symbol->NumberOfAuxSymbols == 1 &&
171 "Exepected a single aux symbol to describe this section!");
172
173 const object::coff_aux_weak_external *ObjWE =
174 reinterpret_cast(
175 AuxData.data());
176 dumpWeakExternal(&Sym, ObjWE);
177 } else if (Symbol->isFileRecord()) {
178 // This symbol represents a file record.
179 Sym.File = StringRef(reinterpret_cast(AuxData.data()),
180 Symbol->NumberOfAuxSymbols * COFF::SymbolSize);
181 } else if (Symbol->isSectionDefinition()) {
182 // This symbol represents a section definition.
183 assert(Symbol->NumberOfAuxSymbols == 1 &&
184 "Expected a single aux symbol to describe this section!");
185
186 const object::coff_aux_section_definition *ObjSD =
187 reinterpret_cast(
188 AuxData.data());
189 dumpSectionDefinition(&Sym, ObjSD);
190 } else if (Symbol->isCLRToken()) {
191 // This symbol represents a CLR token definition.
192 assert(Symbol->NumberOfAuxSymbols == 1 &&
193 "Expected a single aux symbol to describe this CLR Token");
194
195 const object::coff_aux_clr_token *ObjCLRToken =
196 reinterpret_cast(
197 AuxData.data());
198 dumpCLRTokenDefinition(&Sym, ObjCLRToken);
199 } else {
200 llvm_unreachable("Unhandled auxiliary symbol!");
201 }
202 }
93203 Symbols.push_back(Sym);
94204 }
95205 }
1313
1414 #include "yaml2obj.h"
1515 #include "llvm/ADT/SmallString.h"
16 #include "llvm/ADT/STLExtras.h"
1617 #include "llvm/ADT/StringExtras.h"
1718 #include "llvm/ADT/StringMap.h"
1819 #include "llvm/ADT/StringSwitch.h"
152153 for (std::vector::iterator i = CP.Obj.Symbols.begin(),
153154 e = CP.Obj.Symbols.end();
154155 i != e; ++i) {
155 unsigned AuxBytes = i->AuxiliaryData.binary_size();
156 if (AuxBytes % COFF::SymbolSize != 0) {
157 errs() << "AuxiliaryData size not a multiple of symbol size!\n";
158 return false;
159 }
160 i->Header.NumberOfAuxSymbols = AuxBytes / COFF::SymbolSize;
161 NumberOfSymbols += 1 + i->Header.NumberOfAuxSymbols;
156 uint32_t NumberOfAuxSymbols = 0;
157 if (i->FunctionDefinition)
158 NumberOfAuxSymbols += 1;
159 if (i->bfAndefSymbol)
160 NumberOfAuxSymbols += 1;
161 if (i->WeakExternal)
162 NumberOfAuxSymbols += 1;
163 if (!i->File.empty())
164 NumberOfAuxSymbols +=
165 (i->File.size() + COFF::SymbolSize - 1) / COFF::SymbolSize;
166 if (i->SectionDefinition)
167 NumberOfAuxSymbols += 1;
168 if (i->CLRToken)
169 NumberOfAuxSymbols += 1;
170 i->Header.NumberOfAuxSymbols = NumberOfAuxSymbols;
171 NumberOfSymbols += 1 + NumberOfAuxSymbols;
162172 }
163173
164174 // Store all the allocated start addresses in the header.
191201 template
192202 binary_le_impl binary_le(value_type V) {
193203 return binary_le_impl(V);
204 }
205
206 template
207 struct zeros_impl {
208 zeros_impl() {}
209 };
210
211 template
212 raw_ostream &operator<<(raw_ostream &OS, const zeros_impl &) {
213 char Buffer[NumBytes];
214 memset(Buffer, 0, sizeof(Buffer));
215 OS.write(Buffer, sizeof(Buffer));
216 return OS;
217 }
218
219 template
220 zeros_impl zeros(const T &) {
221 return zeros_impl();
194222 }
195223
196224 bool writeCOFF(COFFParser &CP, raw_ostream &OS) {
252280 << binary_le(i->Header.Type)
253281 << binary_le(i->Header.StorageClass)
254282 << binary_le(i->Header.NumberOfAuxSymbols);
255 i->AuxiliaryData.writeAsBinary(OS);
283
284 if (i->FunctionDefinition)
285 OS << binary_le(i->FunctionDefinition->TagIndex)
286 << binary_le(i->FunctionDefinition->TotalSize)
287 << binary_le(i->FunctionDefinition->PointerToLinenumber)
288 << binary_le(i->FunctionDefinition->PointerToNextFunction)
289 << zeros(i->FunctionDefinition->unused);
290 if (i->bfAndefSymbol)
291 OS << zeros(i->bfAndefSymbol->unused1)
292 << binary_le(i->bfAndefSymbol->Linenumber)
293 << zeros(i->bfAndefSymbol->unused2)
294 << binary_le(i->bfAndefSymbol->PointerToNextFunction)
295 << zeros(i->bfAndefSymbol->unused3);
296 if (i->WeakExternal)
297 OS << binary_le(i->WeakExternal->TagIndex)
298 << binary_le(i->WeakExternal->Characteristics)
299 << zeros(i->WeakExternal->unused);
300 if (!i->File.empty()) {
301 uint32_t NumberOfAuxRecords =
302 (i->File.size() + COFF::SymbolSize - 1) / COFF::SymbolSize;
303 uint32_t NumberOfAuxBytes = NumberOfAuxRecords * COFF::SymbolSize;
304 uint32_t NumZeros = NumberOfAuxBytes - i->File.size();
305 OS.write(i->File.data(), i->File.size());
306 for (uint32_t Padding = 0; Padding < NumZeros; ++Padding)
307 OS.write(0);
308 }
309 if (i->SectionDefinition)
310 OS << binary_le(i->SectionDefinition->Length)
311 << binary_le(i->SectionDefinition->NumberOfRelocations)
312 << binary_le(i->SectionDefinition->NumberOfLinenumbers)
313 << binary_le(i->SectionDefinition->CheckSum)
314 << binary_le(i->SectionDefinition->Number)
315 << binary_le(i->SectionDefinition->Selection)
316 << zeros(i->SectionDefinition->unused);
317 if (i->CLRToken)
318 OS << binary_le(i->CLRToken->AuxType)
319 << zeros(i->CLRToken->unused1)
320 << binary_le(i->CLRToken->SymbolTableIndex)
321 << zeros(i->CLRToken->unused2);
256322 }
257323
258324 // Output string table.