From 4d17cdc704db1da4da9f76adb301db88d8e7bdf4 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Thu, 26 Sep 2019 17:03:20 +0000 Subject: [lld][mach-o] Avoid segfaulting when handling an empty section list. Summary: The following patch avoids segfaulting if the section list is empty when writing a mach-o MH_OBJECT. I ran into this case from a more complicated example trying to dead_strip while using '-r' in lld. I'm not sure if having empty sections is a legal mach-o, but it does seem that other llvm-binutils tools can ingest such a boring object with out issue. Would it be better to emit an error, emit a warning, or do nothing? It seems that adding a warning diagnostic might be helpful to users, as I did not expect to have a section-less object when the linker was done. Reviewers: kledzik, ruiu Subscribers: llvm-commits, jrm Tags: #lld, #llvm Differential Revision: https://reviews.llvm.org/D67735 llvm-svn: 372995 --- .../ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'lld/lib/ReaderWriter') diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp index da27c7cadf9..ab7ea7e07f2 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp @@ -626,17 +626,19 @@ llvm::Error MachOFileLayout::writeSingleSegmentLoadCommand(uint8_t *&lc) { + _file.sections.size() * sizeof(typename T::section); uint8_t *next = lc + seg->cmdsize; memset(seg->segname, 0, 16); + seg->flags = 0; seg->vmaddr = 0; - seg->vmsize = _file.sections.back().address - + _file.sections.back().content.size(); seg->fileoff = _endOfLoadCommands; - seg->filesize = _sectInfo[&_file.sections.back()].fileOffset + - _file.sections.back().content.size() - - _sectInfo[&_file.sections.front()].fileOffset; seg->maxprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE; seg->initprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE; seg->nsects = _file.sections.size(); - seg->flags = 0; + if (seg->nsects) { + seg->vmsize = _file.sections.back().address + + _file.sections.back().content.size(); + seg->filesize = _sectInfo[&_file.sections.back()].fileOffset + + _file.sections.back().content.size() - + _sectInfo[&_file.sections.front()].fileOffset; + } if (_swap) swapStruct(*seg); typename T::section *sout = reinterpret_cast -- cgit v1.2.3