From 1e6b8f552c5b316c2bfd2c25e212326a5093ca47 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 24 Jun 2015 14:48:54 +0000 Subject: [PATCH] Don't get confused with sections whose section number is reserved. It is perfectly possible for SHNDX to contain indexes that have the same value as reserved st_shndx values. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240544 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/ELF.h | 10 +-- include/llvm/Object/ELFObjectFile.h | 7 +- test/MC/ELF/many-sections-3.s | 107 ++++++++++++++++++++++++++++ tools/llvm-readobj/ELFDumper.cpp | 4 +- 4 files changed, 116 insertions(+), 12 deletions(-) create mode 100644 test/MC/ELF/many-sections-3.s diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index e87737dcce7..a9d742d230d 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -401,7 +401,7 @@ public: uint64_t getNumSections() const; uintX_t getStringTableIndex() const; - ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const; + ELF::Elf64_Word getExtendedSymbolTableIndex(const Elf_Sym *symb) const; const Elf_Ehdr *getHeader() const { return Header; } const Elf_Shdr *getSection(const Elf_Sym *symb) const; const Elf_Shdr *getSection(uint32_t Index) const; @@ -510,10 +510,10 @@ void ELFFile::LoadVersionMap() const { } template -ELF::Elf64_Word ELFFile::getSymbolTableIndex(const Elf_Sym *symb) const { - if (symb->st_shndx == ELF::SHN_XINDEX) - return ExtendedSymbolTable.lookup(symb); - return symb->st_shndx; +ELF::Elf64_Word +ELFFile::getExtendedSymbolTableIndex(const Elf_Sym *symb) const { + assert(symb->st_shndx == ELF::SHN_XINDEX); + return ExtendedSymbolTable.lookup(symb); } template diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index b4f7fe2603c..93bfd60cf52 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -278,7 +278,7 @@ template std::error_code ELFObjectFile::getSymbolAddress(DataRefImpl Symb, uint64_t &Result) const { const Elf_Sym *ESym = getSymbol(Symb); - switch (EF.getSymbolTableIndex(ESym)) { + switch (ESym->st_shndx) { case ELF::SHN_COMMON: case ELF::SHN_UNDEF: Result = UnknownAddress; @@ -383,11 +383,10 @@ uint32_t ELFObjectFile::getSymbolFlags(DataRefImpl Symb) const { EIter == EF.begin_symbols() || EIter == EF.begin_dynamic_symbols()) Result |= SymbolRef::SF_FormatSpecific; - if (EF.getSymbolTableIndex(ESym) == ELF::SHN_UNDEF) + if (ESym->st_shndx == ELF::SHN_UNDEF) Result |= SymbolRef::SF_Undefined; - if (ESym->getType() == ELF::STT_COMMON || - EF.getSymbolTableIndex(ESym) == ELF::SHN_COMMON) + if (ESym->getType() == ELF::STT_COMMON || ESym->st_shndx == ELF::SHN_COMMON) Result |= SymbolRef::SF_Common; if (isExportedToOtherDSO(ESym)) diff --git a/test/MC/ELF/many-sections-3.s b/test/MC/ELF/many-sections-3.s new file mode 100644 index 00000000000..02d30a60523 --- /dev/null +++ b/test/MC/ELF/many-sections-3.s @@ -0,0 +1,107 @@ +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t +// RUN: llvm-readobj -t %t | FileCheck --check-prefix=SYMBOLS %s +// RUN: llvm-nm %t | FileCheck --check-prefix=NM %s + +// Test that symbol a has a section that could be confused with common (0xFFF2) +// SYMBOLS: Name: a +// SYMBOLS-NEXT: Value: 0x0 +// SYMBOLS-NEXT: Size: 0 +// SYMBOLS-NEXT: Binding: Local (0x0) +// SYMBOLS-NEXT: Type: None (0x0) +// SYMBOLS-NEXT: Other: 0 +// SYMBOLS-NEXT: Section: bar (0xFFF2) +// SYMBOLS-NEXT: } + +// Test that we don't get confused +// NM: 0000000000000000 r a + +.macro gen_sections4 x + .section a\x + .section b\x + .section c\x + .section d\x +.endm + +.macro gen_sections8 x + gen_sections4 a\x + gen_sections4 b\x +.endm + +.macro gen_sections16 x + gen_sections8 a\x + gen_sections8 b\x +.endm + +.macro gen_sections32 x + gen_sections16 a\x + gen_sections16 b\x +.endm + +.macro gen_sections64 x + gen_sections32 a\x + gen_sections32 b\x +.endm + +.macro gen_sections128 x + gen_sections64 a\x + gen_sections64 b\x +.endm + +.macro gen_sections256 x + gen_sections128 a\x + gen_sections128 b\x +.endm + +.macro gen_sections512 x + gen_sections256 a\x + gen_sections256 b\x +.endm + +.macro gen_sections1024 x + gen_sections512 a\x + gen_sections512 b\x +.endm + +.macro gen_sections2048 x + gen_sections1024 a\x + gen_sections1024 b\x +.endm + +.macro gen_sections4096 x + gen_sections2048 a\x + gen_sections2048 b\x +.endm + +.macro gen_sections8192 x + gen_sections4096 a\x + gen_sections4096 b\x +.endm + +.macro gen_sections16384 x + gen_sections8192 a\x + gen_sections8192 b\x +.endm + +.macro gen_sections32768 x + gen_sections16384 a\x + gen_sections16384 b\x +.endm + +gen_sections32768 a +gen_sections16384 b +gen_sections8192 c +gen_sections4096 d +gen_sections2048 e +gen_sections1024 f +gen_sections512 g +gen_sections256 h +gen_sections128 i +gen_sections64 j +gen_sections32 k +gen_sections8 l +gen_sections4 m + + .section foo + .section bar, "a" + +a: diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index 59a351d5299..d8c089a63e3 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -156,9 +156,7 @@ getSectionNameIndex(const ELFO &Obj, typename ELFO::Elf_Sym_Iter Symbol, SectionName = "Reserved"; else { if (SectionIndex == SHN_XINDEX) - SectionIndex = Obj.getSymbolTableIndex(&*Symbol); - assert(SectionIndex != SHN_XINDEX && - "getSymbolTableIndex should handle this"); + SectionIndex = Obj.getExtendedSymbolTableIndex(&*Symbol); const typename ELFO::Elf_Shdr *Sec = Obj.getSection(SectionIndex); SectionName = errorOrDefault(Obj.getSectionName(Sec)); } -- 2.34.1