in MachOObjectFile::getSymbolByIndex() when a Mach-O file has
a symbol table load command but the number of symbols are zero.
The code in MachOObjectFile::symbol_begin_impl() should not be
assuming there is a symbol at index 0, in cases there is no symbol
table load command or the count of symbol is zero. So I also fixed
that. And needed to fix MachOObjectFile::symbol_end_impl() to
also do the same thing for no symbol table or one with zero entries.
The code in MachOObjectFile::getSymbolByIndex() should trigger
the report_fatal_error() for programmatic errors for any index when
there is no symbol table load command and not return the end iterator.
So also fixed that. Note there is no test case as this is a programmatic
error.
The test case using the file macho-invalid-bad-symbol-index has
a symbol table load command with its number of symbols (nsyms)
is zero. Which was incorrectly testing the bad triggering of the
report_fatal_error() in in MachOObjectFile::getSymbolByIndex().
This test case is an invalid Mach-O file but not for that reason.
It appears this Mach-O file use to have an nsyms value of 11,
and what makes this Mach-O file invalid is the counts and
indexes into the symbol table of the dynamic load command
are now invalid because the number of symbol table entries
(nsyms) is now zero. Which can be seen with the existing
llvm-obdump:
% llvm-objdump -private-headers macho-invalid-bad-symbol-index
…
Load command 4
cmd LC_SYMTAB
cmdsize 24
symoff 4216
nsyms 0
stroff 4392
strsize 144
Load command 5
cmd LC_DYSYMTAB
cmdsize 80
ilocalsym 0
nlocalsym 8 (past the end of the symbol table)
iextdefsym 8 (greater than the number of symbols)
nextdefsym 2 (past the end of the symbol table)
iundefsym 10 (greater than the number of symbols)
nundefsym 1 (past the end of the symbol table)
...
And the native darwin tools generates an error for this file:
% nm macho-invalid-bad-symbol-index
nm: object: macho-invalid-bad-symbol-index truncated or malformed object (ilocalsym plus nlocalsym in LC_DYSYMTAB load command extends past the end of the symbol table)
I added new checks for the indexes and sizes for these in the
constructor of MachOObjectFile. And added comments for what
would be a proper diagnostic messages.
And changed the test case using macho-invalid-bad-symbol-index
to test for the new error now produced.
Also added a test with a valid Mach-O file with a symbol table
load command where the number of symbols is zero that shows
the report_fatal_error() is not called.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@258576 91177308-0d34-0410-b5e6-96231b3b80d8
but to return object_error::parse_failed. Then made the code in llvm-nm
do for Mach-O files what is done in the darwin native tools which is to
print "bad string index" for bad string indexes. Updated the error message
in the llvm-objdump test, and added tests to show llvm-nm prints
"bad string index" and a test to print the actual bad string index value
which in this case is 0xfe000002 when printing the fields as raw hex.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@258520 91177308-0d34-0410-b5e6-96231b3b80d8
but to return object_error::parse_failed. Then made the code in llvm-nm
do for Mach-O files what is done in the darwin native tools which is to
print "(?,?)" or just "s" for bad section indexes. Also added a test to show
it prints the bad section index of "42" when printing the fields as raw hex.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@258434 91177308-0d34-0410-b5e6-96231b3b80d8
In `MachOObjectFile::getSymbolType` we currently always return `SymbolRef::ST_Function` for symbols from any section. In order for llvm-symbolizer to correctly symbolize Mach-O globals, symbols from data and BSS sections should return `SymbolRef::ST_Data`.
Differential Revision: http://reviews.llvm.org/D14576
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252867 91177308-0d34-0410-b5e6-96231b3b80d8
from malformed Mach-O files that caused a crash because of a
section header had a size that extended past the end of the file.
rdar://22983603
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249768 91177308-0d34-0410-b5e6-96231b3b80d8
While introducing support for MinVersionLoadCommand in llvm-readobj I noticed there's
no API to extract Major/Minor/Update components conveniently. Currently consumers
do the bit twiddling on their own, but this will change from now on.
I'll convert llvm-objdump (and llvm-readobj) in a later commit.
Differential Revision: http://reviews.llvm.org/D12282
Reviewed by: rafael
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245938 91177308-0d34-0410-b5e6-96231b3b80d8
This function can actually fail since the symbol contains an index to the
section and that can be invalid.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@244375 91177308-0d34-0410-b5e6-96231b3b80d8
getSymbolValue now returns a value that in convenient for most callers:
* 0 for undefined
* symbol size for common symbols
* offset/address for symbols the rest
Code that needs something more specific can check getSymbolFlags.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241605 91177308-0d34-0410-b5e6-96231b3b80d8
At least not in the interface exposed by ObjectFile. This matches what ELF and
COFF implement.
Adjust existing code that was expecting them to have values. No overall
functionality change intended.
Another option would be to change the interface and the ELF and COFF
implementations to say that the value of a common symbol is its size.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241593 91177308-0d34-0410-b5e6-96231b3b80d8
They are implemented like that in some object formats, but for the interface
provided by lib/Object, SF_Undefined and SF_Common are different things.
This matches the ELF and COFF implementation and fixes llvm-nm for MachO.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241587 91177308-0d34-0410-b5e6-96231b3b80d8
In these two contexts we really just want the raw n_value. No need to use
getSymbolValue which checks for special cases where, semantically, the symbol
has no value.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241584 91177308-0d34-0410-b5e6-96231b3b80d8
Originally added in r139314.
Back then it didn't actually get the address, it got whatever value the
relocation used: address or offset.
The values in different object formats are:
* MachO: Always an offset.
* COFF: Always an address, but when talking about the virtual address of
sections it says: "for simplicity, compilers should set this to zero".
* ELF: An offset for .o files and and address for .so files. In the case of the
.so, the relocation in not linked to any section (sh_info is 0). We can't
really compute an offset.
Some API mappings would be:
* Use getAddress for everything. It would be quite cumbersome. To compute the
address elf has to follow sh_info, which can be corrupted and therefore the
method has to return an ErrorOr. The address of the section is also the same
for every relocation in a section, so we shouldn't have to check the error
and fetch the value for every relocation.
* Use a getValue and make it up to the user to know what it is getting.
* Use a getOffset and:
* Assert for dynamic ELF objects. That is a very peculiar case and it is
probably fair to ask any tool that wants to support it to use ELF.h. The
only tool we have that reads those (llvm-readobj) already does that. The
only other use case I can think of is a dynamic linker.
* Check that COFF .obj files have sections with zero virtual address spaces. If
it turns out that some assembler/compiler produces these, we can change
COFFObjectFile::getRelocationOffset to subtract it. Given COFF format,
this can be done without the need for ErrorOr.
The getRelocationAddress method was never implemented for COFF. It also
had exactly one use in a very peculiar case: a shortcut for adding the
section value to a pcrel reloc on MachO.
Given that, I don't expect that there is any use out there of the C API. If
that is not the case, let me know and I will add it back with the implementation
inlined and do a proper deprecation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241450 91177308-0d34-0410-b5e6-96231b3b80d8
This function can really fail since the string table offset can be out of
bounds.
Using ErrorOr makes sure the error is checked.
Hopefully a lot of the boilerplate code in tools/* can go away once we have
a diagnostic manager in Object.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241297 91177308-0d34-0410-b5e6-96231b3b80d8
We can probably do better in this method, but this is an improvement and
enables further ErrorOr cleanups.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241114 91177308-0d34-0410-b5e6-96231b3b80d8
This is still a really odd function. Most calls are in object format specific
contexts and should probably be replaced with a more direct query, but at least
now this is not too obnoxious to use.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240777 91177308-0d34-0410-b5e6-96231b3b80d8
On ELF that was already the case since getting the size of a symbol
never fails.
On MachO and COFF we could fail trying to get the section of a symbol. But
we don't really need the section, just the section number to know if two
symbols are in the same section or not.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240580 91177308-0d34-0410-b5e6-96231b3b80d8
This returns either the symbol offset or address. Since it is not defined which
one, it never has to lookup the section and so never fails.
I will add users in the next commit.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240569 91177308-0d34-0410-b5e6-96231b3b80d8
COFF and MachO only define symbol sizes for common symbols. Reflect that
in the class hierarchy by having a method for common symbols only in the base
and a general one in ELF.
This avoids the need of using a magic value for the size, which had a few
problems
* Most callers didn't check for it.
* The ones that did could not tell the magic value from a file actually having
that value.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240529 91177308-0d34-0410-b5e6-96231b3b80d8
In a relocation target can take 3 basic forms
* A r_value in scattered relocations.
* A symbol in external relocations.
* A section is non-external relocations.
Have the dump reflect that. With this change we go from
CHECK-NEXT: Extern: 0
CHECK-NEXT: Type: X86_64_RELOC_SUBTRACTOR (5)
CHECK-NEXT: Symbol: 0x2
CHECK-NEXT: Scattered: 0
To just
// CHECK-NEXT: Type: X86_64_RELOC_SUBTRACTOR (5)
// CHECK-NEXT: Section: __data (2)
Since the relocation is with a section, we print the seciton name and don't
need to say that it is not scattered or external.
Someone motivated can add further special cases for things like
ARM64_RELOC_ADDEND and ARM_RELOC_PAIR.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240073 91177308-0d34-0410-b5e6-96231b3b80d8
make_error_code(object_error) is slow because object::object_category()
uses a ManagedStatic variable. But the real problem is that the function is
called too frequently. This patch uses std::error_code() instead of
object_error::success. In most cases, we return "success", so this patch
reduces number of function calls to that function.
http://reviews.llvm.org/D10333
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239409 91177308-0d34-0410-b5e6-96231b3b80d8
Report proper error code from MachOObjectFile constructor if we
can't parse another segment load command (we already return a proper
error if segment load command contents is suspicious).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239109 91177308-0d34-0410-b5e6-96231b3b80d8
Summary:
Properly report the error in segment load commands from MachOObjectFile
constructor instead of crashing the program.
Adjust the test case accordingly.
Test Plan: regression test suite
Reviewers: rafael, filcab
Subscribers: llvm-commits
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239081 91177308-0d34-0410-b5e6-96231b3b80d8
Summary:
Currently all load commands are parsed in MachOObjectFile constructor.
If the next load command cannot be parsed, or if command size is too
small, properly report it through the error code and fail to construct
the object, instead of crashing the program.
Test Plan: regression test suite
Reviewers: rafael, filcab
Subscribers: llvm-commits
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239080 91177308-0d34-0410-b5e6-96231b3b80d8
Summary: Instead, properly report this error from MachOObjectFile constructor.
Test Plan: regression test suite
Reviewers: rafael
Subscribers: llvm-commits
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239078 91177308-0d34-0410-b5e6-96231b3b80d8
Summary:
Avoid parsing object file each time MachOObjectFile::getHeader() is
called. Instead, cache the header in MachOObjectFile constructor, where
it's parsed anyway. In future, we must avoid constructing the object
at all if the header can't be parsed.
Test Plan: regression test suite.
Reviewers: rafael
Subscribers: llvm-commits
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239075 91177308-0d34-0410-b5e6-96231b3b80d8
Summary:
Now users don't have to manually deal with getFirstLoadCommandInfo() /
getNextLoadCommandInfo(), calculate the number of load segments, etc.
No functionality change.
Test Plan: regression test suite
Reviewers: rafael, lhames, loladiro
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D10144
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238983 91177308-0d34-0410-b5e6-96231b3b80d8