diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -106,8 +106,8 @@ Optional Section; Optional Index; ELF_STB Binding; - llvm::yaml::Hex64 Value; - llvm::yaml::Hex64 Size; + Optional Value; + Optional Size; Optional Other; Optional StName; diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -837,9 +837,9 @@ else if (Sym.Index) Symbol.st_shndx = *Sym.Index; - Symbol.st_value = Sym.Value; + Symbol.st_value = Sym.Value.getValueOr(yaml::Hex64(0)); Symbol.st_other = Sym.Other ? *Sym.Other : 0; - Symbol.st_size = Sym.Size; + Symbol.st_size = Sym.Size.getValueOr(yaml::Hex64(0)); } return Ret; diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -1089,8 +1089,8 @@ IO.mapOptional("Section", Symbol.Section); IO.mapOptional("Index", Symbol.Index); IO.mapOptional("Binding", Symbol.Binding, ELFYAML::ELF_STB(0)); - IO.mapOptional("Value", Symbol.Value, Hex64(0)); - IO.mapOptional("Size", Symbol.Size, Hex64(0)); + IO.mapOptional("Value", Symbol.Value); + IO.mapOptional("Size", Symbol.Size); // Symbol's Other field is a bit special. It is usually a field that // represents st_other and holds the symbol visibility. However, on some diff --git a/llvm/test/tools/obj2yaml/ELF/symbol.yaml b/llvm/test/tools/obj2yaml/ELF/symbol.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/obj2yaml/ELF/symbol.yaml @@ -0,0 +1,27 @@ +## This is a test case to check how obj2yaml dumps symbols. + +## Check that we only dump Size and Value keys when +## their values are not 0. + +# RUN: yaml2obj %s -o %t1 +# RUN: obj2yaml %t1 | FileCheck %s --check-prefix=FIELDS-DEF + +# FIELDS-DEF: Symbols: +# FIELDS-DEF-NEXT: - Name: foo +# FIELDS-DEF-NEXT: - Name: bar +# FIELDS-DEF-NEXT: Value: 0x1 +# FIELDS-DEF-NEXT: Size: 0x1 +# FIELDS-DEF-NEXT: ... + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL +Symbols: + - Name: foo + Size: 0x0 + Value: 0x0 + - Name: bar + Size: 0x1 + Value: 0x1 diff --git a/llvm/test/tools/yaml2obj/ELF/symbol-size.yaml b/llvm/test/tools/yaml2obj/ELF/symbol-size.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/yaml2obj/ELF/symbol-size.yaml @@ -0,0 +1,33 @@ +## Check we can set different sizes for symbols. + +# RUN: yaml2obj %s -o %t +# RUN: llvm-readelf --symbols %t | FileCheck %s + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL +Symbols: +## No "Size" key was set. Check the behaviour is the +## same as if it was set to 0. + - Name: aaa +# CHECK: Num: Value Size {{.*}} Name +# CHECK: 1: [[#]] 0 {{.*}} aaa +## The "Size" key is explicitly set to 0x0. + - Name: bbb + Size: 0x0 +## Check we can use the "=" syntax. +# CHECK-NEXT: 2: [[#]] 0 {{.*}} bbb + - Name: ccc + Size: [[ESIZE=]] +# CHECK-NEXT: 3: [[#]] 0 {{.*}} ccc +## "Size" is explicitly set to an arbitrary value. +## Here we use UINT64_MAX to check this boundary case. + - Name: ddd + Size: 0xffffffffffffffff +# CHECK-NEXT: 4: [[#]] -1 {{.*}} ddd +## The same as the previous case, but using decimal values. + - Name: eee + Size: 18446744073709551615 +# CHECK-NEXT: 5: [[#]] -1 {{.*}} eee diff --git a/llvm/test/tools/yaml2obj/ELF/symbol-value.yaml b/llvm/test/tools/yaml2obj/ELF/symbol-value.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/yaml2obj/ELF/symbol-value.yaml @@ -0,0 +1,33 @@ +## Check we can set different values for symbols. + +# RUN: yaml2obj %s -o %t +# RUN: llvm-readelf --symbols %t | FileCheck %s + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL +Symbols: +## No "Value" key was set. Check the behaviour is the +## same as if it was set to 0. + - Name: aaa +# CHECK: Num: Value {{.*}} Name +# CHECK: 1: 0000000000000000 {{.*}} aaa +## The "Value" key is explicitly set to 0x0. + - Name: bbb + Value: 0x0 +## Check we can use the "=" syntax. +# CHECK-NEXT: 2: 0000000000000000 {{.*}} bbb + - Name: ccc + Value: [[EVAL=]] +# CHECK-NEXT: 3: 0000000000000000 {{.*}} ccc +## The "Value" key is explicitly set to an arbitrary value. +## Here we use UINT64_MAX to check this boundary case. + - Name: ddd + Value: 0xffffffffffffffff +# CHECK-NEXT: 4: ffffffffffffffff {{.*}} ddd +## The same as the previous case, but using decimal values. + - Name: eee + Value: 18446744073709551615 +# CHECK-NEXT: 5: ffffffffffffffff {{.*}} eee diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -661,8 +661,10 @@ Error ELFDumper::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab, StringRef StrTable, ELFYAML::Symbol &S) { S.Type = Sym->getType(); - S.Value = Sym->st_value; - S.Size = Sym->st_size; + if (Sym->st_value) + S.Value = (yaml::Hex64)Sym->st_value; + if (Sym->st_size) + S.Size = (yaml::Hex64)Sym->st_size; S.Other = Sym->st_other; S.Binding = Sym->getBinding();