Index: test/tools/llvm-objcopy/abs-symbol.test =================================================================== --- /dev/null +++ test/tools/llvm-objcopy/abs-symbol.test @@ -0,0 +1,36 @@ +# RUN: yaml2obj %s > %t +# RUN: llvm-objcopy %t %t2 +# RUN: llvm-readobj -symbols %t2 | FileCheck %s + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Symbols: + Global: + - Name: test + Index: SHN_ABS + Value: 0x1234 + +#CHECK: Symbols [ +#CHECK-NEXT: Symbol { +#CHECK-NEXT: Name: +#CHECK-NEXT: Value: 0x0 +#CHECK-NEXT: Size: 0 +#CHECK-NEXT: Binding: Local (0x0) +#CHECK-NEXT: Type: None (0x0) +#CHECK-NEXT: Other: 0 +#CHECK-NEXT: Section: Undefined (0x0) +#CHECK-NEXT: } +#CHECK-NEXT: Symbol { +#CHECK-NEXT: Name: test +#CHECK-NEXT: Value: 0x1234 +#CHECK-NEXT: Size: 0 +#CHECK-NEXT: Binding: Global (0x1) +#CHECK-NEXT: Type: None (0x0) +#CHECK-NEXT: Other: 0 +#CHECK-NEXT: Section: Absolute (0xFFF1) +#CHECK-NEXT: } +#CHECK-NEXT:] Index: test/tools/llvm-objcopy/section-index-unsupported.test =================================================================== --- /dev/null +++ test/tools/llvm-objcopy/section-index-unsupported.test @@ -0,0 +1,13 @@ +# RUN: yaml2obj %s > %t +# RUN: not llvm-objcopy %t %t2 + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Symbols: + Global: + - Name: test + Index: 0xff05 Index: tools/llvm-objcopy/Object.h =================================================================== --- tools/llvm-objcopy/Object.h +++ tools/llvm-objcopy/Object.h @@ -116,6 +116,7 @@ struct Symbol { uint8_t Binding; SectionBase *DefinedIn; + uint32_t SectionIndex; uint32_t Index; llvm::StringRef Name; uint32_t NameIndex; @@ -132,7 +133,8 @@ public: void setStrTab(StringTableSection *StrTab) { SymbolNames = StrTab; } void addSymbol(llvm::StringRef Name, uint8_t Bind, uint8_t Type, - SectionBase *DefinedIn, uint64_t Value, uint64_t Sz); + SectionBase *DefinedIn, uint64_t Value, uint32_t SectionIndex, + uint64_t Sz); void addSymbolNames(); const Symbol *getSymbolByIndex(uint32_t Index) const; void finalize() override; Index: tools/llvm-objcopy/Object.cpp =================================================================== --- tools/llvm-objcopy/Object.cpp +++ tools/llvm-objcopy/Object.cpp @@ -92,7 +92,7 @@ void SymbolTableSection::addSymbol(StringRef Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn, uint64_t Value, - uint64_t Sz) { + uint32_t SectionIndex, uint64_t Sz) { Symbol Sym; Sym.Name = Name; Sym.Binding = Bind; @@ -101,6 +101,7 @@ Sym.Value = Value; Sym.Size = Sz; Sym.Index = Symbols.size(); + Sym.SectionIndex = SectionIndex; Symbols.emplace_back(llvm::make_unique(Sym)); Size += this->EntrySize; } @@ -114,6 +115,9 @@ Sym->NameIndex = SymbolNames->findIndex(Sym->Name); if (Sym->Binding == STB_LOCAL) MaxLocalIndex = std::max(MaxLocalIndex, Sym->Index); + + if (Sym->DefinedIn) + Sym->SectionIndex = Sym->DefinedIn->Index; } // Now we need to set the Link and Info fields. Link = SymbolNames->Index; @@ -146,10 +150,7 @@ Sym->st_size = Symbol->Size; Sym->setBinding(Symbol->Binding); Sym->setType(Symbol->Type); - if (Symbol->DefinedIn) - Sym->st_shndx = Symbol->DefinedIn->Index; - else - Sym->st_shndx = SHN_UNDEF; + Sym->st_shndx = Symbol->SectionIndex; ++Sym; } } @@ -196,6 +197,20 @@ } } +bool isSupportedSectionIndex(uint32_t Index) { + switch(Index) { + case SHN_ABS: + case SHN_COMMON: + case SHN_HEXAGON_SCOMMON: + case SHN_HEXAGON_SCOMMON_2: + case SHN_HEXAGON_SCOMMON_4: + case SHN_HEXAGON_SCOMMON_8: + return true; + default: + return false; + } +} + template void Object::initSymbolTable(const llvm::object::ELFFile &ElfFile, SymbolTableSection *SymTab) { @@ -218,7 +233,13 @@ for (const auto &Sym : unwrapOrError(ElfFile.symbols(&Shdr))) { SectionBase *DefSection = nullptr; StringRef Name = unwrapOrError(Sym.getName(StrTabData)); - if (Sym.st_shndx != SHN_UNDEF) { + if (Sym.st_shndx >= SHN_LORESERVE) { + if (!isSupportedSectionIndex(Sym.st_shndx)) { + error("Symbol '" + Name + + "' has unsupported value greater than SHN_LORESERVE: " + + Twine(Sym.st_shndx)); + } + } else if (Sym.st_shndx != SHN_UNDEF) { if (Sym.st_shndx >= Sections.size()) error("Symbol '" + Name + "' is defined in invalid section with index " + @@ -226,7 +247,7 @@ DefSection = Sections[Sym.st_shndx - 1].get(); } SymTab->addSymbol(Name, Sym.getBinding(), Sym.getType(), DefSection, - Sym.getValue(), Sym.st_size); + Sym.getValue(), Sym.st_shndx, Sym.st_size); } }