diff --git a/llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml b/llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml --- a/llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml +++ b/llvm/test/tools/obj2yaml/ELF/gnu-hash-section.yaml @@ -54,9 +54,12 @@ # INVALID-NEXT: - Name: .gnu.hash.broken.maskwords # INVALID-NEXT: Type: SHT_GNU_HASH # INVALID-NEXT: Content: '00000000000000000100000000000000' -# INVALID-NEXT: - Name: .gnu.hash.broken.nbuckets +# INVALID-NEXT: - Name: .gnu.hash.broken.nbuckets.a # INVALID-NEXT: Type: SHT_GNU_HASH # INVALID-NEXT: Content: '01000000000000000000000000000000' +# INVALID-NEXT: - Name: .gnu.hash.broken.nbuckets.b +# INVALID-NEXT: Type: SHT_GNU_HASH +# INVALID-NEXT: Content: FFFFFFFF000000000100000000000000{{$}} # INVALID-NEXT: - Name: .gnu.hash.hashvalues.ok # INVALID-NEXT: Type: SHT_GNU_HASH # INVALID-NEXT: Header: @@ -108,9 +111,9 @@ BloomFilter: [] HashBuckets: [] HashValues: [] -## Case 4: NBuckets field is broken, it says that the number of entries +## Case 4(a): NBuckets field is broken, it says that the number of entries ## in the hash buckets is 1, but it is empty. - - Name: .gnu.hash.broken.nbuckets + - Name: .gnu.hash.broken.nbuckets.a Type: SHT_GNU_HASH Header: SymNdx: 0x0 @@ -120,6 +123,18 @@ BloomFilter: [] HashBuckets: [] HashValues: [] +## Case 4(b): NBuckets = 0xFFFFFFFF is incorrect. The result will cause 32-bit +## unsigned overflows if we keep intermediate expressions uint32_t. + - Name: .gnu.hash.broken.nbuckets.b + Type: SHT_GNU_HASH + Header: + SymNdx: 0x0 + Shift2: 0x0 + MaskWords: 0x1 + NBuckets: 0xFFFFFFFF + BloomFilter: [] + HashBuckets: [] + HashValues: [] ## Case 5: Check that we use the various properties to dump the data when it ## has a size that is a multiple of 4, but fallback to dumping the whole section ## using the "Content" property otherwise. 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 @@ -1271,9 +1271,9 @@ ELFYAML::GnuHashHeader Header; DataExtractor::Cursor Cur(0); - uint32_t NBuckets = Data.getU32(Cur); + uint64_t NBuckets = Data.getU32(Cur); Header.SymNdx = Data.getU32(Cur); - uint32_t MaskWords = Data.getU32(Cur); + uint64_t MaskWords = Data.getU32(Cur); Header.Shift2 = Data.getU32(Cur); // Set just the raw binary content if we were unable to read the header