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 @@ -203,6 +203,9 @@ // The following members are used to override section fields which is // useful for creating invalid objects. + // This can be used to override the sh_addralign field. + Optional ShAddrAlign; + // 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; 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 @@ -552,6 +552,8 @@ static void overrideFields(ELFYAML::Section *From, typename ELFT::Shdr &To) { if (!From) return; + if (From->ShAddrAlign) + To.sh_addralign = *From->ShAddrAlign; if (From->ShFlags) To.sh_flags = *From->ShFlags; if (From->ShName) 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 @@ -1113,9 +1113,9 @@ // 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() && - !Section.ShName.hasValue() && !Section.ShFlags.hasValue() && - !Section.ShType.hasValue())); + (!Section.ShOffset && !Section.ShSize && !Section.ShName && + !Section.ShFlags && !Section.ShType && !Section.ShAddrAlign)); + IO.mapOptional("ShAddrAlign", Section.ShAddrAlign); IO.mapOptional("ShName", Section.ShName); IO.mapOptional("ShOffset", Section.ShOffset); IO.mapOptional("ShSize", Section.ShSize); diff --git a/llvm/test/tools/yaml2obj/ELF/override-shaddralign.yaml b/llvm/test/tools/yaml2obj/ELF/override-shaddralign.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/yaml2obj/ELF/override-shaddralign.yaml @@ -0,0 +1,30 @@ +## Check we are able to set a custom sh_addralign field for different sections +## and that doing this does not affect the output size. + +## Test that we are able to override the sh_addralign section +## field with use of the "ShAddrAlign" key. + +# RUN: yaml2obj %s -o %t +# RUN: llvm-readelf --sections %t | FileCheck %s --check-prefix=CHECK + +# CHECK: Section Headers: +# CHECK-NEXT: [Nr] Name {{.*}} Off Size ES Flg Lk Inf Al +# CHECK-NEXT: [ 0] {{.*}} 000000 000000 00 0 0 0 +# CHECK-NEXT: [ 1] .foo {{.*}} 000080 000000 00 0 0 1229782938247303441 +# CHECK-NEXT: [ 2] .bar {{.*}} 000100 000000 00 0 0 2459565876494606882 +# CHECK-NEXT: [ 3] .strtab {{.*}} 000100 000001 00 0 0 1 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL +Sections: + - Name: .foo + Type: SHT_PROGBITS + AddressAlign: 0x80 + ShAddrAlign: 0x1111111111111111 + - Name: .bar + Type: SHT_PROGBITS + AddressAlign: 0x100 + ShAddrAlign: 0x2222222222222222