diff options
author | Matt Davis <nullptr@fb.com> | 2019-09-26 17:03:20 +0000 |
---|---|---|
committer | Matt Davis <nullptr@fb.com> | 2019-09-26 17:03:20 +0000 |
commit | 4d17cdc704db1da4da9f76adb301db88d8e7bdf4 (patch) | |
tree | 4bef18d1086e84acd5d3a6b689ddde44fe7fdf6b /lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp | |
parent | 01ba7d5efe18b9dd14a5c2bb1f692702513d66f7 (diff) | |
download | bcm5719-llvm-4d17cdc704db1da4da9f76adb301db88d8e7bdf4.tar.gz bcm5719-llvm-4d17cdc704db1da4da9f76adb301db88d8e7bdf4.zip |
[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
Diffstat (limited to 'lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp')
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp | 14 |
1 files changed, 8 insertions, 6 deletions
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<typename T::section*> |