From a1c861d379ffeec421c2be1f5adc1edc04a187c3 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Mon, 7 Apr 2014 23:12:20 +0000 Subject: [PATCH] obj2yaml: Use the correct relocation type for different machine types The IO normalizer would essentially lump I386 and AMD64 relocations together. Relocation types with the same numeric value would then get mapped in appropriately. For example: IMAGE_REL_AMD64_ADDR64 and IMAGE_REL_I386_DIR16 both have a numeric value of one. We would see IMAGE_REL_I386_DIR16 in obj2yaml conversions of object files with a machine type of IMAGE_FILE_MACHINE_AMD64. llvm-svn: 205746 --- llvm/include/llvm/Object/COFFYAML.h | 9 +++-- llvm/include/llvm/Support/COFF.h | 6 ++-- llvm/lib/Object/COFFYAML.cpp | 32 +++++++++++++----- llvm/test/Object/Inputs/COFF/x86-64.yaml | 17 ++++++++++ .../Inputs/trivial-object-test.coff-x86-64 | Bin 347 -> 437 bytes llvm/test/Object/obj2yaml.test | 20 +++++++++-- 6 files changed, 70 insertions(+), 14 deletions(-) diff --git a/llvm/include/llvm/Object/COFFYAML.h b/llvm/include/llvm/Object/COFFYAML.h index b5f9cccf85d4..3f48e07f575a 100644 --- a/llvm/include/llvm/Object/COFFYAML.h +++ b/llvm/include/llvm/Object/COFFYAML.h @@ -121,8 +121,13 @@ struct ScalarEnumerationTraits { }; template <> -struct ScalarEnumerationTraits { - static void enumeration(IO &IO, COFF::RelocationTypeX86 &Value); +struct ScalarEnumerationTraits { + static void enumeration(IO &IO, COFF::RelocationTypeI386 &Value); +}; + +template <> +struct ScalarEnumerationTraits { + static void enumeration(IO &IO, COFF::RelocationTypeAMD64 &Value); }; template <> diff --git a/llvm/include/llvm/Support/COFF.h b/llvm/include/llvm/Support/COFF.h index dca7fc6ee898..f0e5c7dc6287 100644 --- a/llvm/include/llvm/Support/COFF.h +++ b/llvm/include/llvm/Support/COFF.h @@ -275,7 +275,7 @@ namespace COFF { uint16_t Type; }; - enum RelocationTypeX86 { + enum RelocationTypeI386 { IMAGE_REL_I386_ABSOLUTE = 0x0000, IMAGE_REL_I386_DIR16 = 0x0001, IMAGE_REL_I386_REL16 = 0x0002, @@ -286,8 +286,10 @@ namespace COFF { IMAGE_REL_I386_SECREL = 0x000B, IMAGE_REL_I386_TOKEN = 0x000C, IMAGE_REL_I386_SECREL7 = 0x000D, - IMAGE_REL_I386_REL32 = 0x0014, + IMAGE_REL_I386_REL32 = 0x0014 + }; + enum RelocationTypeAMD64 { IMAGE_REL_AMD64_ABSOLUTE = 0x0000, IMAGE_REL_AMD64_ADDR64 = 0x0001, IMAGE_REL_AMD64_ADDR32 = 0x0002, diff --git a/llvm/lib/Object/COFFYAML.cpp b/llvm/lib/Object/COFFYAML.cpp index 94b72ffcbf3f..d05576fc49d3 100644 --- a/llvm/lib/Object/COFFYAML.cpp +++ b/llvm/lib/Object/COFFYAML.cpp @@ -132,8 +132,8 @@ void ScalarEnumerationTraits::enumeration( ECase(IMAGE_SYM_DTYPE_ARRAY); } -void ScalarEnumerationTraits::enumeration( - IO &IO, COFF::RelocationTypeX86 &Value) { +void ScalarEnumerationTraits::enumeration( + IO &IO, COFF::RelocationTypeI386 &Value) { ECase(IMAGE_REL_I386_ABSOLUTE); ECase(IMAGE_REL_I386_DIR16); ECase(IMAGE_REL_I386_REL16); @@ -145,6 +145,10 @@ void ScalarEnumerationTraits::enumeration( ECase(IMAGE_REL_I386_TOKEN); ECase(IMAGE_REL_I386_SECREL7); ECase(IMAGE_REL_I386_REL32); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, COFF::RelocationTypeAMD64 &Value) { ECase(IMAGE_REL_AMD64_ABSOLUTE); ECase(IMAGE_REL_AMD64_ADDR64); ECase(IMAGE_REL_AMD64_ADDR32); @@ -272,22 +276,33 @@ struct NHeaderCharacteristics { COFF::Characteristics Characteristics; }; +template struct NType { - NType(IO &) : Type(COFF::RelocationTypeX86(0)) {} - NType(IO &, uint16_t T) : Type(COFF::RelocationTypeX86(T)) {} + NType(IO &) : Type(RelocType(0)) {} + NType(IO &, uint16_t T) : Type(RelocType(T)) {} uint16_t denormalize(IO &) { return Type; } - COFF::RelocationTypeX86 Type; + RelocType Type; }; } void MappingTraits::mapping(IO &IO, COFFYAML::Relocation &Rel) { - MappingNormalization NT(IO, Rel.Type); - IO.mapRequired("VirtualAddress", Rel.VirtualAddress); IO.mapRequired("SymbolName", Rel.SymbolName); - IO.mapRequired("Type", NT->Type); + + COFF::header &H = *static_cast(IO.getContext()); + if (H.Machine == COFF::IMAGE_FILE_MACHINE_I386) { + MappingNormalization, uint16_t> NT( + IO, Rel.Type); + IO.mapRequired("Type", NT->Type); + } else if (H.Machine == COFF::IMAGE_FILE_MACHINE_AMD64) { + MappingNormalization, uint16_t> NT( + IO, Rel.Type); + IO.mapRequired("Type", NT->Type); + } else { + IO.mapRequired("Type", Rel.Type); + } } void MappingTraits::mapping(IO &IO, COFF::header &H) { @@ -297,6 +312,7 @@ void MappingTraits::mapping(IO &IO, COFF::header &H) { IO.mapRequired("Machine", NM->Machine); IO.mapOptional("Characteristics", NC->Characteristics); + IO.setContext(static_cast(&H)); } void MappingTraits::mapping( diff --git a/llvm/test/Object/Inputs/COFF/x86-64.yaml b/llvm/test/Object/Inputs/COFF/x86-64.yaml index 1dc2b10cf410..b8a863a429cd 100644 --- a/llvm/test/Object/Inputs/COFF/x86-64.yaml +++ b/llvm/test/Object/Inputs/COFF/x86-64.yaml @@ -30,6 +30,16 @@ sections: Characteristics: [IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE, ] # 0xc0100040 SectionData: !hex "48656C6C6F20576F726C642100" # |Hello World!.| + - !Section + Name: '.CRT$XCU' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + Alignment: 8 + SectionData: !hex "0000000000000000" + Relocations: + - VirtualAddress: 0 + SymbolName: '??__Ex@@YAXXZ' + Type: IMAGE_REL_AMD64_ADDR64 + symbols: - !Symbol Name: .text @@ -91,3 +101,10 @@ symbols: ComplexType: IMAGE_SYM_DTYPE_NULL # (0) StorageClass: IMAGE_SYM_CLASS_EXTERNAL # (2) + - !Symbol + Name: '??__Ex@@YAXXZ' + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL # (0) + ComplexType: IMAGE_SYM_DTYPE_FUNCTION # (2) + StorageClass: IMAGE_SYM_CLASS_STATIC # (3) diff --git a/llvm/test/Object/Inputs/trivial-object-test.coff-x86-64 b/llvm/test/Object/Inputs/trivial-object-test.coff-x86-64 index 077591482cea64b9fba25cfc15c4f7bd7ab3e077..ed144d1265f3946a17d35fd04f5fce01da7612a8 100644 GIT binary patch delta 162 zcmcc3w3V4RrHz>Z1l|KN=R{s<)*c{Z(?nfm#tRbzg*Eh?gF;jyoI^oMK!5{??*j2t z5C;etf!Kk;!C_)bpdeTPN`TZcPTUgCq`)wlm(juuBrFD%V`flbU}jJO@`CeoQ~gUa dQj6S5^O8$4^Ya+&?c?KJD;yjm9U~&57yzjy9FG71 delta 71 zcmdnWe4B|krHzRpy`|4*D+2=q$3$Lf))XM4Yoe|)