--- /dev/null
+# RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+# RUN: obj2yaml %t.o | FileCheck %s
+
+# CHECK: Sections:
+# CHECK: - Name: .group{{$}}
+# CHECK: Members:
+# CHECK: - SectionOrType: .text.foo{{$}}
+# CHECK: - SectionOrType: .rela.text.foo{{$}}
+# CHECK: - Name: .text.foo{{$}}
+# CHECK: - Name: .rela.text.foo{{$}}
+# CHECK: Info: .text.foo{{$}}
+# CHECK: - Name: .group1{{$}}
+# CHECK: Members:
+# CHECK: - SectionOrType: .text.foo2{{$}}
+# CHECK: - SectionOrType: .rela.text.foo3{{$}}
+# CHECK: - Name: .text.foo2{{$}}
+# CHECK: - Name: .rela.text.foo3{{$}}
+# CHECK: Info: .text.foo2{{$}}
+# CHECK: Symbols:
+# CHECK: Section: .group{{$}}
+# CHECK: Section: .group1{{$}}
+
+
+ .section .text.foo,"axG",@progbits,sym1,comdat
+ .quad undef
+
+ .section .text.foo,"axG",@progbits,sym2,comdat
+ .quad undef
#include "Error.h"
#include "obj2yaml.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/ObjectYAML/ELFYAML.h"
typedef typename object::ELFFile<ELFT>::Elf_Rel Elf_Rel;
typedef typename object::ELFFile<ELFT>::Elf_Rela Elf_Rela;
+ ArrayRef<Elf_Shdr> Sections;
+
+ // If the file has multiple sections with the same name, we add a
+ // suffix to make them unique.
+ unsigned Suffix = 0;
+ DenseSet<StringRef> UsedSectionNames;
+ std::vector<std::string> SectionNames;
+ Expected<StringRef> getUniquedSectionName(const Elf_Shdr *Sec);
+
const object::ELFFile<ELFT> &Obj;
ArrayRef<Elf_Word> ShndxTable;
: Obj(O) {}
template <class ELFT>
-ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
+Expected<StringRef>
+ELFDumper<ELFT>::getUniquedSectionName(const Elf_Shdr *Sec) {
+ unsigned SecIndex = Sec - &Sections[0];
+ assert(&Sections[SecIndex] == Sec);
+ if (!SectionNames[SecIndex].empty())
+ return SectionNames[SecIndex];
+
+ auto NameOrErr = Obj.getSectionName(Sec);
+ if (!NameOrErr)
+ return NameOrErr;
+ StringRef Name = *NameOrErr;
+ std::string Ret = Name;
+ while (!UsedSectionNames.insert(Ret).second)
+ Ret = (Name + to_string(++Suffix)).str();
+ SectionNames[SecIndex] = Ret;
+ return SectionNames[SecIndex];
+}
+
+template <class ELFT> ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
auto Y = make_unique<ELFYAML::Object>();
// Dump header
auto SectionsOrErr = Obj.sections();
if (!SectionsOrErr)
return errorToErrorCode(SectionsOrErr.takeError());
- for (const Elf_Shdr &Sec : *SectionsOrErr) {
+ Sections = *SectionsOrErr;
+ SectionNames.resize(Sections.size());
+ for (const Elf_Shdr &Sec : Sections) {
switch (Sec.sh_type) {
case ELF::SHT_NULL:
case ELF::SHT_DYNSYM:
if (!Shdr)
return obj2yaml_error::success;
- auto NameOrErr = Obj.getSectionName(Shdr);
+ auto NameOrErr = getUniquedSectionName(Shdr);
if (!NameOrErr)
return errorToErrorCode(NameOrErr.takeError());
S.Section = NameOrErr.get();
S.Address = Shdr->sh_addr;
S.AddressAlign = Shdr->sh_addralign;
- auto NameOrErr = Obj.getSectionName(Shdr);
+ auto NameOrErr = getUniquedSectionName(Shdr);
if (!NameOrErr)
return errorToErrorCode(NameOrErr.takeError());
S.Name = NameOrErr.get();
auto LinkSection = Obj.getSection(Shdr->sh_link);
if (LinkSection.takeError())
return errorToErrorCode(LinkSection.takeError());
- NameOrErr = Obj.getSectionName(*LinkSection);
+ NameOrErr = getUniquedSectionName(*LinkSection);
if (!NameOrErr)
return errorToErrorCode(NameOrErr.takeError());
S.Link = NameOrErr.get();
if (!InfoSection)
return errorToErrorCode(InfoSection.takeError());
- auto NameOrErr = Obj.getSectionName(*InfoSection);
+ auto NameOrErr = getUniquedSectionName(*InfoSection);
if (!NameOrErr)
return errorToErrorCode(NameOrErr.takeError());
S.Info = NameOrErr.get();
auto sHdr = Obj.getSection(groupMembers[i]);
if (!sHdr)
return errorToErrorCode(sHdr.takeError());
- auto sectionName = Obj.getSectionName(*sHdr);
+ auto sectionName = getUniquedSectionName(*sHdr);
if (!sectionName)
return errorToErrorCode(sectionName.takeError());
s.sectionNameOrType = *sectionName;