diff options
| -rw-r--r-- | llvm/test/tools/llvm-readobj/elf-hash-symbols.test | 40 | ||||
| -rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 11 | 
2 files changed, 51 insertions, 0 deletions
diff --git a/llvm/test/tools/llvm-readobj/elf-hash-symbols.test b/llvm/test/tools/llvm-readobj/elf-hash-symbols.test index b0140a2e9c1..4ffecf9fcc6 100644 --- a/llvm/test/tools/llvm-readobj/elf-hash-symbols.test +++ b/llvm/test/tools/llvm-readobj/elf-hash-symbols.test @@ -361,3 +361,43 @@ ProgramHeaders:      PAddr: 0x1000      Sections:        - Section: .dynamic + +## Show that we report a warning for a hash table which contains an entry of +## the bucket array pointing to a cycle. + +# RUN: yaml2obj --docnum=6 %s -o %t6.so +# RUN: llvm-readelf --hash-symbols %t6.so 2>&1 | FileCheck %s -DFILE=%t6.so --check-prefix=BROKEN + +# BROKEN:      Symbol table of .hash for image: +# BROKEN-NEXT:  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name +# BROKEN-NEXT:    1   0: 00000000     0 NOTYPE  LOCAL  DEFAULT UND aaa +# BROKEN: warning: '[[FILE]]': .hash section is invalid: bucket 1: a cycle was detected in the linked chain + +--- !ELF +FileHeader: +  Class:   ELFCLASS32 +  Data:    ELFDATA2LSB +  Type:    ET_DYN +  Machine: EM_386 +Sections: +  - Name:    .hash +    Type:    SHT_HASH +    Link:    .dynsym +    Bucket:  [ 1 ] +    Chain:   [ 1, 1 ] +  - Name:  .dynamic +    Type:  SHT_DYNAMIC +    Entries: +## llvm-readelf will read the hash table from the file offset +## p_offset + (p_vaddr - DT_HASH) = p_offset + (0 - 0) = p_offset, +## which is the start of PT_LOAD, i.e. the file offset of .hash. +      - Tag:   DT_HASH +        Value: 0x0 +DynamicSymbols: +  - Name:    aaa +  - Name:    bbb +ProgramHeaders: +  - Type:  PT_LOAD +    Sections: +      - Section: .hash +      - Section: .dynamic diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index af3d0e967d1..1b3e8f4851d 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -3437,10 +3437,21 @@ template <class ELFT> void GNUStyle<ELFT>::printHashSymbols(const ELFO *Obj) {      for (uint32_t Buc = 0; Buc < SysVHash->nbucket; Buc++) {        if (Buckets[Buc] == ELF::STN_UNDEF)          continue; +      std::vector<bool> Visited(SysVHash->nchain);        for (uint32_t Ch = Buckets[Buc]; Ch < SysVHash->nchain; Ch = Chains[Ch]) {          if (Ch == ELF::STN_UNDEF)            break; + +        if (Visited[Ch]) { +          reportWarning( +              createError(".hash section is invalid: bucket " + Twine(Ch) + +                          ": a cycle was detected in the linked chain"), +              this->FileName); +          break; +        } +          printHashedSymbol(Obj, &DynSyms[0], Ch, StringTable, Buc); +        Visited[Ch] = true;        }      }    }  | 

