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
Patch by Nicholas Allegra.
The Mach-O writer calculates the size of load commands multiple times.
First, Util::assignAddressesToSections() (in MachONormalizedFileFromAtoms.cpp)
calculates the size using headerAndLoadCommandsSize() (in
MachONormalizedFileBinaryWriter.cpp), which creates a temporary
MachOFileLayout for the NormalizedFile, only to retrieve its
headerAndLoadCommandsSize. Later, writeBinary() (in
MachONormalizedFileBinaryWriter.cpp) creates a new layout and uses the offsets
from that layout to actually write out everything in the NormalizedFile.
But the NormalizedFile changes between the first computation and the second.
When Util::assignAddressesToSections is called, file.functionStarts is always
empty because Util::addFunctionStarts has not yet been called. Yet
MachOFileLayout decides whether to include a LC_FUNCTION_STARTS command based
on whether file.functionStarts is nonempty. Therefore, the initial computation
always omits it.
Because padding for the __TEXT segment (to make its size a multiple of the
page size) is added between the load commands and the first section, LLD still
generates a valid binary as long as the amount of padding happens to be large
enough to fit LC_FUNCTION_STARTS command, which it usually is.
However, it's easy to reproduce the issue by adding a section of a precise
size. Given foo.c:
__attribute__((section("__TEXT,__foo")))
char foo[0xd78] = {0};
Run:
clang -dynamiclib -o foo.dylib foo.c -fuse-ld=lld -install_name
/usr/lib/foo.dylib
otool -lvv foo.dylib
This should produce:
truncated or malformed object (offset field of section 1 in LC_SEGMENT_64
command 0 not past the headers of the file)
This commit:
- Changes MachOFileLayout to always assume LC_FUNCTION_STARTS is present for
the initial computation, as long as generating LC_FUNCTION_STARTS is
enabled. It would be slightly better to check whether there are actually
any functions, since no LC_FUNCTION_STARTS will be generated if not, but it
doesn't cause a problem if the initial computation is too high.
- Adds a test.
- Adds an assert in MachOFileLayout::writeSectionContent() that we are not
writing section content into the load commands region (which would happen
if the offset was calculated too low due to the initial load commands size
calculation being too low). Adds an assert in
MachOFileLayout::writeLoadCommands to validate a similar situation where
two size-of-load-commands computations are expected to be equivalent.
llvm-svn: 358545
to reflect the new license.
We understand that people may be surprised that we're moving the header
entirely to discuss the new license. We checked this carefully with the
Foundation's lawyer and we believe this is the correct approach.
Essentially, all code in the project is now made available by the LLVM
project under our new license, so you will see that the license headers
include that license only. Some of our contributors have contributed
code under our old license, and accordingly, we have retained a copy of
our old license notice in the top-level files in each project and
repository.
llvm-svn: 351636
New lld's files are spread under lib subdirectory, and it isn't easy
to find which files are actually maintained. This patch moves maintained
files to Common subdirectory.
Differential Revision: https://reviews.llvm.org/D37645
llvm-svn: 314719
This creates a new library called BinaryFormat that has all of
the headers from llvm/Support containing structure and layout
definitions for various types of binary formats like dwarf, coff,
elf, etc as well as the code for identifying a file from its
magic.
Differential Revision: https://reviews.llvm.org/D33843
llvm-svn: 304864
We should be using one of BIND_OPCODE_SET_DYLIB_SPECIAL_IMM, BIND_OPCODE_SET_DYLIB_ORDINAL_IMM,
and BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB depending on whether ordinals are <= 0, <= 15, > 15.
This matches the behaviour of ld64.
llvm-svn: 278407
We already had logic for binding opcodes had the same addend as last time. This adds
the cases where the ordinal, symbol name, type, and segment offsets are the same as
the last emitted ordinal.
This gets us one step closer to emitting rebase opcodes as compressed as ld64 can manage.
llvm-svn: 278405
Using vmsize to populate this file works when outputing MachO images, but fails
when outputting relocatable objects. This patch fixes the computation to use
file offsets, which works for both output types.
Fixes <rdar://problem/27727666>
llvm-svn: 278297
The export trie was being emitted in the order the nodes were
added to the vector, but instead needs to be visited in the order
that the nodes are traversed. This matches the behaviour of ld64.
llvm-svn: 277869
This patch causes LLD to build stabs debugging symbols for files containing
DWARF debug info, and to propagate existing stabs symbols for object files
built using '-r' mode. This enables debugging of binaries generated by LLD
from MachO objects.
llvm-svn: 276921
These methods were responsible for some of the few remaining calls
to llvm::errorCodeToError. Converting them makes us have more Error's
in the api and fewer error_code's.
llvm-svn: 264974
On a 32-bit output, we may write LC_MAIN (which contains a uint64_t) to
an unaligned address. This changes it to use a memcpy instead which is UB safe.
llvm-svn: 264232