diff --git a/lld/lib/ReaderWriter/ELF/ReaderELF.cpp b/lld/lib/ReaderWriter/ELF/ReaderELF.cpp index 5aa5e91a78c5..365150ae9e09 100644 --- a/lld/lib/ReaderWriter/ELF/ReaderELF.cpp +++ b/lld/lib/ReaderWriter/ELF/ReaderELF.cpp @@ -278,17 +278,37 @@ public: virtual ContentType contentType() const { - if (_symbol->getType() == llvm::ELF::STT_FUNC) - return typeCode; + ContentType ret = typeUnknown; - if ((_symbol->getType() == llvm::ELF::STT_COMMON) - || _symbol->st_shndx == llvm::ELF::SHN_COMMON) - return typeZeroFill; - if (_symbol->getType() == llvm::ELF::STT_OBJECT) - return typeData; - - return typeUnknown; + switch (_section->sh_type) { + case llvm::ELF::SHT_PROGBITS: + case llvm::ELF::SHT_DYNAMIC: + switch (_section->sh_flags) { + case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR): + ret = typeCode; + break; + case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE): + ret = typeData; + break; + case llvm::ELF::SHF_ALLOC: + case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE): + case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE | + llvm::ELF::SHF_STRINGS): + ret = typeConstant; + break; + } + break; + case llvm::ELF::SHT_NOBITS: + ret = typeZeroFill; + break; + case llvm::ELF::SHT_NULL: + if ((_symbol->getType() == llvm::ELF::STT_COMMON) + || _symbol->st_shndx == llvm::ELF::SHN_COMMON) + ret = typeZeroFill; + break; + } + return ret; } virtual Alignment alignment() const { diff --git a/lld/test/elf/Inputs/rodata-test.hexagon b/lld/test/elf/Inputs/rodata-test.hexagon new file mode 100644 index 000000000000..f448748e2abe Binary files /dev/null and b/lld/test/elf/Inputs/rodata-test.hexagon differ diff --git a/lld/test/elf/Inputs/rodata-test.i386 b/lld/test/elf/Inputs/rodata-test.i386 new file mode 100644 index 000000000000..09f71eb59969 Binary files /dev/null and b/lld/test/elf/Inputs/rodata-test.i386 differ diff --git a/lld/test/elf/check.objtxt b/lld/test/elf/check.objtxt index 8a09e661e0c7..cb0f6bb92883 100644 --- a/lld/test/elf/check.objtxt +++ b/lld/test/elf/check.objtxt @@ -1,5 +1,5 @@ RUN: lld-core -reader ELF %p/Inputs/object-test.elf-i386 | FileCheck %s -check-prefix ELF-i386 -RUN: lld-core -reader ELF %p/Inputs/object-test.elf-hexagon | FileCheck %s -check-prefix ELF-hexagon +RUN: lld-core -arch hexagon -reader ELF %p/Inputs/object-test.elf-hexagon | FileCheck %s -check-prefix ELF-hexagon ELF-i386:atoms: ELF-i386: - name: global_func diff --git a/lld/test/elf/rodata.objtxt b/lld/test/elf/rodata.objtxt new file mode 100644 index 000000000000..4773e0c7789d --- /dev/null +++ b/lld/test/elf/rodata.objtxt @@ -0,0 +1,7 @@ +RUN: lld-core -reader ELF -writer ELF -o %t1 %p/Inputs/rodata-test.i386 | llvm-objdump -section-headers %t1 | FileCheck -check-prefix=i386 %s +RUN: lld-core -arch hexagon -reader ELF -writer ELF -o %t2 %p/Inputs/rodata-test.hexagon | llvm-objdump -section-headers %t2 | FileCheck -check-prefix=hexagon %s + + i386: 4 .rodata 000000004 + + hexagon: 5 .rodata 000000004 + diff --git a/lld/test/elf/sections.objtxt b/lld/test/elf/sections.objtxt index d47d9d176386..84c78711df36 100644 --- a/lld/test/elf/sections.objtxt +++ b/lld/test/elf/sections.objtxt @@ -2,13 +2,14 @@ RUN: lld-core -reader ELF -writer ELF -o %t1 %p/Inputs/section-test.i386 | llvm- RUN: llvm-readobj %t1 | FileCheck -check-prefix=READOBJ %s RUN: elf-dump --dump-section %t1 | FileCheck -check-prefix=ED %s -OBJDUMP: 0 000000000 00000000000000000 -OBJDUMP: 1 .text 00000000a 0000000000000014c TEXT DATA -OBJDUMP: 2 .data 000000004 00000000000000158 DATA -OBJDUMP: 3 .special 000000004 0000000000000015c DATA -OBJDUMP: 4 .anotherspecial 000000004 00000000000000160 DATA -OBJDUMP: 5 .bss 000000000 00000000000000164 BSS -OBJDUMP: 6 .shstrtab 000000035 00000000000000164 +OBJDUMP: 0 000000000 00000000000000000 +OBJDUMP: 1 .text 00000000a 00000000000000174 TEXT DATA +OBJDUMP: 2 .data 000000004 00000000000000180 DATA +OBJDUMP: 3 .bss 000000000 00000000000000184 BSS +OBJDUMP: 4 .special 000000004 00000000000000184 DATA +OBJDUMP: 5 .anotherspecial 000000004 00000000000000188 DATA +OBJDUMP: 6 000000000 0000000000000018c BSS +OBJDUMP: 7 .shstrtab 000000036 0000000000000018c READOBJ: File Format : ELF32-i386 READOBJ: Arch : i386 diff --git a/lld/tools/lld-core/lld-core.cpp b/lld/tools/lld-core/lld-core.cpp index b78ae07680db..9a004cb18164 100644 --- a/lld/tools/lld-core/lld-core.cpp +++ b/lld/tools/lld-core/lld-core.cpp @@ -114,7 +114,23 @@ readerSelected("reader", clEnumValN(readerELF, "ELF", "read as linux would"), clEnumValEnd)); - +enum ArchChoice { + i386 = llvm::ELF::EM_386, + x86_64 = llvm::ELF::EM_X86_64, + hexagon = llvm::ELF::EM_HEXAGON +}; +llvm::cl::opt +archSelected("arch", + llvm::cl::desc("Select architecture, only valid with ELF output"), + llvm::cl::values( + clEnumValN(i386, "i386", + "output i386, EM_386 file"), + clEnumValN(x86_64, + "x86_64", "output x86_64, EM_X86_64 file"), + clEnumValN(hexagon, + "hexagon", "output Hexagon, EM_HEXAGON file"), + clEnumValEnd)); + class TestingResolverOptions : public ResolverOptions { public: @@ -146,12 +162,18 @@ int main(int argc, char *argv[]) { if (cmdLineOutputFilePath.empty()) cmdLineOutputFilePath.assign("-"); - // create writer for final output + // create writer for final output, default to i386 if none selected + WriterOptionsELF writerOptionsELF(false, llvm::support::little, + llvm::ELF::ET_EXEC, + archSelected.getValue() == 0 + ? i386 + : archSelected); + TestingWriterOptionsYAML writerOptionsYAML(cmdLineDoStubsPass, cmdLineDoGotPass); WriterOptionsMachO writerOptionsMachO; WriterOptionsPECOFF writerOptionsPECOFF; - WriterOptionsELF writerOptionsELF; + Writer* writer = nullptr; switch ( writeSelected ) { case writeYAML: