Index: include/llvm/ObjectYAML/ELFYAML.h =================================================================== --- include/llvm/ObjectYAML/ELFYAML.h +++ include/llvm/ObjectYAML/ELFYAML.h @@ -139,14 +139,6 @@ llvm::yaml::Hex64 AddressAlign; Optional EntSize; - // This can be used to override the sh_offset field. It does not place the - // section data at the offset specified. Useful for creating invalid objects. - Optional ShOffset; - - // This can be used to override the sh_size field. It does not affect the - // content written. - Optional ShSize; - // Usually sections are not created implicitly, but loaded from YAML. // When they are, this flag is used to signal about that. bool IsImplicit; @@ -154,6 +146,21 @@ Section(SectionKind Kind, bool IsImplicit = false) : Kind(Kind), IsImplicit(IsImplicit) {} virtual ~Section(); + + // The following members are used to override section fields which is + // useful for creating invalid objects. + + // This can be used to override the offset stored in the sh_name field. + // It does not affect the name stored in the string table + Optional ShName; + + // This can be used to override the sh_offset field. It does not place the + // section data at the offset specified. + Optional ShOffset; + + // This can be used to override the sh_size field. It does not affect the + // content written. + Optional ShSize; }; struct DynamicSection : Section { Index: lib/ObjectYAML/ELFEmitter.cpp =================================================================== --- lib/ObjectYAML/ELFEmitter.cpp +++ lib/ObjectYAML/ELFEmitter.cpp @@ -292,8 +292,10 @@ else return false; - // Override the sh_offset/sh_size fields if requested. + // Override the fields if requested. if (YAMLSec) { + if (YAMLSec->ShName) + Header.sh_name = *YAMLSec->ShName; if (YAMLSec->ShOffset) Header.sh_offset = *YAMLSec->ShOffset; if (YAMLSec->ShSize) @@ -397,6 +399,8 @@ // Override the sh_offset/sh_size fields if requested. if (Sec) { + if (Sec->ShName) + SHeader.sh_name = *Sec->ShName; if (Sec->ShOffset) SHeader.sh_offset = *Sec->ShOffset; if (Sec->ShSize) Index: lib/ObjectYAML/ELFYAML.cpp =================================================================== --- lib/ObjectYAML/ELFYAML.cpp +++ lib/ObjectYAML/ELFYAML.cpp @@ -986,10 +986,11 @@ IO.mapOptional("EntSize", Section.EntSize); // obj2yaml does not dump these fields. They are expected to be empty when we - // are producing YAML, because yaml2obj sets appropriate values for sh_offset - // and sh_size automatically when they are not explicitly defined. + // are producing YAML, because yaml2obj sets appropriate values for them + // automatically when they are not explicitly defined. assert(!IO.outputting() || (!Section.ShOffset.hasValue() && !Section.ShSize.hasValue())); + IO.mapOptional("ShName", Section.ShName); IO.mapOptional("ShOffset", Section.ShOffset); IO.mapOptional("ShSize", Section.ShSize); } Index: test/tools/yaml2obj/elf-override-shname.yaml =================================================================== --- /dev/null +++ test/tools/yaml2obj/elf-override-shname.yaml @@ -0,0 +1,88 @@ +## Check we are able to set a custom sh_name field for different sections +## and that doing this does not affect the names stored in the string table. + +# RUN: yaml2obj %s -o %t1 +# RUN: llvm-readobj --sections --section-data %t1 | FileCheck %s + +# CHECK: Index: 1 +# CHECK-NEXT: Name:{{.* }}(1) +# CHECK: Index: 2 +# CHECK-NEXT: Name:{{.* }}(2) +# CHECK: Index: 3 +# CHECK-NEXT: Name:{{.* }}(3) +# CHECK: Index: 4 +# CHECK-NEXT: Name:{{.* }}(4) +# CHECK: Index: 5 +# CHECK-NEXT: Name:{{.* }}(5) +# CHECK: Index: 6 +# CHECK-NEXT: Name:{{.* }}(6) +# CHECK: Index: 7 +# CHECK-NEXT: Name:{{.* }}(7) +# CHECK: Index: 8 +# CHECK-NEXT: Name:{{.* }}(8) +# CHECK: Index: 9 +# CHECK-NEXT: Name:{{.* }}(9) +# CHECK: Index: 10 +# CHECK-NEXT: Name:{{.* }}(10) +# CHECK: Index: 11 +# CHECK-NEXT: Name:{{.* }}(11) + +# CHECK: Name: .shstrtab +# CHECK: SectionData ( +# CHECK-NEXT: |..nobits..regula| +# CHECK-NEXT: |r..gnu.version_r| +# CHECK-NEXT: |..group..gnu.ver| +# CHECK-NEXT: |sion..dynsym..gn| +# CHECK-NEXT: |u.version_d..dyn| +# CHECK-NEXT: |amic..shstrtab..| +# CHECK-NEXT: |strtab..symtab..| +# CHECK-NEXT: |rela.| +# CHECK-NEXT: ) + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .dynsym + Type: SHT_DYNSYM + ShName: 0x000000001 + - Name: .symtab + Type: SHT_SYMTAB + ShName: 0x000000002 + - Name: .dynamic + Type: SHT_DYNAMIC + ShName: 0x000000003 + - Name: .rela + Type: SHT_RELA + ShName: 0x000000004 + - Name: .nobits + Type: SHT_NOBITS + ShName: 0x000000005 + - Name: .group + Type: SHT_GROUP + Info: 0 + ShName: 0x000000006 + Members: + - Name: .gnu.version + Type: SHT_GNU_versym + Entries: [ ] + ShName: 0x000000007 + - Name: .gnu.version_r + Type: SHT_GNU_verneed + Info: 0x0000000000000001 + ShName: 0x000000008 + Dependencies: + - Name: .gnu.version_d + Type: SHT_GNU_verdef + Info: 0x0000000000000001 + ShName: 0x000000009 + Entries: + - Name: .regular + Type: SHT_PROGBITS + ShName: 0x00000000A + - Name: .strtab + Type: SHT_STRTAB + ShName: 0x00000000B