You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.167
Former-commit-id: 289509151e0fee68a1b591a20c9f109c3c789d3a
This commit is contained in:
parent
e19d552987
commit
b084638f15
993
external/llvm/lib/Object/Archive.cpp
vendored
993
external/llvm/lib/Object/Archive.cpp
vendored
File diff suppressed because it is too large
Load Diff
532
external/llvm/lib/Object/ArchiveWriter.cpp
vendored
532
external/llvm/lib/Object/ArchiveWriter.cpp
vendored
File diff suppressed because it is too large
Load Diff
100
external/llvm/lib/Object/Binary.cpp
vendored
100
external/llvm/lib/Object/Binary.cpp
vendored
@ -1,100 +0,0 @@
|
||||
//===- Binary.cpp - A generic binary file ---------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the Binary class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Object/Binary.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/BinaryFormat/Magic.h"
|
||||
#include "llvm/Object/Archive.h"
|
||||
#include "llvm/Object/Error.h"
|
||||
#include "llvm/Object/MachOUniversal.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Object/WindowsResource.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/ErrorOr.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <system_error>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace object;
|
||||
|
||||
Binary::~Binary() = default;
|
||||
|
||||
Binary::Binary(unsigned int Type, MemoryBufferRef Source)
|
||||
: TypeID(Type), Data(Source) {}
|
||||
|
||||
StringRef Binary::getData() const { return Data.getBuffer(); }
|
||||
|
||||
StringRef Binary::getFileName() const { return Data.getBufferIdentifier(); }
|
||||
|
||||
MemoryBufferRef Binary::getMemoryBufferRef() const { return Data; }
|
||||
|
||||
Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
|
||||
LLVMContext *Context) {
|
||||
file_magic Type = identify_magic(Buffer.getBuffer());
|
||||
|
||||
switch (Type) {
|
||||
case file_magic::archive:
|
||||
return Archive::create(Buffer);
|
||||
case file_magic::elf:
|
||||
case file_magic::elf_relocatable:
|
||||
case file_magic::elf_executable:
|
||||
case file_magic::elf_shared_object:
|
||||
case file_magic::elf_core:
|
||||
case file_magic::macho_object:
|
||||
case file_magic::macho_executable:
|
||||
case file_magic::macho_fixed_virtual_memory_shared_lib:
|
||||
case file_magic::macho_core:
|
||||
case file_magic::macho_preload_executable:
|
||||
case file_magic::macho_dynamically_linked_shared_lib:
|
||||
case file_magic::macho_dynamic_linker:
|
||||
case file_magic::macho_bundle:
|
||||
case file_magic::macho_dynamically_linked_shared_lib_stub:
|
||||
case file_magic::macho_dsym_companion:
|
||||
case file_magic::macho_kext_bundle:
|
||||
case file_magic::coff_object:
|
||||
case file_magic::coff_import_library:
|
||||
case file_magic::pecoff_executable:
|
||||
case file_magic::bitcode:
|
||||
case file_magic::wasm_object:
|
||||
return ObjectFile::createSymbolicFile(Buffer, Type, Context);
|
||||
case file_magic::macho_universal_binary:
|
||||
return MachOUniversalBinary::create(Buffer);
|
||||
case file_magic::windows_resource:
|
||||
return WindowsResource::createWindowsResource(Buffer);
|
||||
case file_magic::unknown:
|
||||
case file_magic::coff_cl_gl_object:
|
||||
// Unrecognized object file format.
|
||||
return errorCodeToError(object_error::invalid_file_type);
|
||||
}
|
||||
llvm_unreachable("Unexpected Binary File Type");
|
||||
}
|
||||
|
||||
Expected<OwningBinary<Binary>> object::createBinary(StringRef Path) {
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
|
||||
MemoryBuffer::getFileOrSTDIN(Path);
|
||||
if (std::error_code EC = FileOrErr.getError())
|
||||
return errorCodeToError(EC);
|
||||
std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get();
|
||||
|
||||
Expected<std::unique_ptr<Binary>> BinOrErr =
|
||||
createBinary(Buffer->getMemBufferRef());
|
||||
if (!BinOrErr)
|
||||
return BinOrErr.takeError();
|
||||
std::unique_ptr<Binary> &Bin = BinOrErr.get();
|
||||
|
||||
return OwningBinary<Binary>(std::move(Bin), std::move(Buffer));
|
||||
}
|
31
external/llvm/lib/Object/CMakeLists.txt
vendored
31
external/llvm/lib/Object/CMakeLists.txt
vendored
@ -1,31 +0,0 @@
|
||||
add_llvm_library(LLVMObject
|
||||
Archive.cpp
|
||||
ArchiveWriter.cpp
|
||||
Binary.cpp
|
||||
COFFImportFile.cpp
|
||||
COFFModuleDefinition.cpp
|
||||
COFFObjectFile.cpp
|
||||
Decompressor.cpp
|
||||
ELF.cpp
|
||||
ELFObjectFile.cpp
|
||||
Error.cpp
|
||||
IRObjectFile.cpp
|
||||
IRSymtab.cpp
|
||||
MachOObjectFile.cpp
|
||||
MachOUniversal.cpp
|
||||
ModuleSymbolTable.cpp
|
||||
Object.cpp
|
||||
ObjectFile.cpp
|
||||
RecordStreamer.cpp
|
||||
SymbolicFile.cpp
|
||||
SymbolSize.cpp
|
||||
WasmObjectFile.cpp
|
||||
WindowsResource.cpp
|
||||
|
||||
ADDITIONAL_HEADER_DIRS
|
||||
${LLVM_MAIN_INCLUDE_DIR}/llvm/Object
|
||||
|
||||
DEPENDS
|
||||
intrinsics_gen
|
||||
llvm_vcsrevision_h
|
||||
)
|
610
external/llvm/lib/Object/COFFImportFile.cpp
vendored
610
external/llvm/lib/Object/COFFImportFile.cpp
vendored
File diff suppressed because it is too large
Load Diff
360
external/llvm/lib/Object/COFFModuleDefinition.cpp
vendored
360
external/llvm/lib/Object/COFFModuleDefinition.cpp
vendored
@ -1,360 +0,0 @@
|
||||
//===--- COFFModuleDefinition.cpp - Simple DEF parser ---------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Windows-specific.
|
||||
// A parser for the module-definition file (.def file).
|
||||
//
|
||||
// The format of module-definition files are described in this document:
|
||||
// https://msdn.microsoft.com/en-us/library/28d6s79h.aspx
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Object/COFFModuleDefinition.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/Object/COFF.h"
|
||||
#include "llvm/Object/COFFImportFile.h"
|
||||
#include "llvm/Object/Error.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm::COFF;
|
||||
using namespace llvm;
|
||||
|
||||
namespace llvm {
|
||||
namespace object {
|
||||
|
||||
enum Kind {
|
||||
Unknown,
|
||||
Eof,
|
||||
Identifier,
|
||||
Comma,
|
||||
Equal,
|
||||
KwBase,
|
||||
KwConstant,
|
||||
KwData,
|
||||
KwExports,
|
||||
KwHeapsize,
|
||||
KwLibrary,
|
||||
KwName,
|
||||
KwNoname,
|
||||
KwPrivate,
|
||||
KwStacksize,
|
||||
KwVersion,
|
||||
};
|
||||
|
||||
struct Token {
|
||||
explicit Token(Kind T = Unknown, StringRef S = "") : K(T), Value(S) {}
|
||||
Kind K;
|
||||
StringRef Value;
|
||||
};
|
||||
|
||||
static bool isDecorated(StringRef Sym, bool MingwDef) {
|
||||
// In def files, the symbols can either be listed decorated or undecorated.
|
||||
//
|
||||
// - For cdecl symbols, only the undecorated form is allowed.
|
||||
// - For fastcall and vectorcall symbols, both fully decorated or
|
||||
// undecorated forms can be present.
|
||||
// - For stdcall symbols in non-MinGW environments, the decorated form is
|
||||
// fully decorated with leading underscore and trailing stack argument
|
||||
// size - like "_Func@0".
|
||||
// - In MinGW def files, a decorated stdcall symbol does not include the
|
||||
// leading underscore though, like "Func@0".
|
||||
|
||||
// This function controls whether a leading underscore should be added to
|
||||
// the given symbol name or not. For MinGW, treat a stdcall symbol name such
|
||||
// as "Func@0" as undecorated, i.e. a leading underscore must be added.
|
||||
// For non-MinGW, look for '@' in the whole string and consider "_Func@0"
|
||||
// as decorated, i.e. don't add any more leading underscores.
|
||||
// We can't check for a leading underscore here, since function names
|
||||
// themselves can start with an underscore, while a second one still needs
|
||||
// to be added.
|
||||
return Sym.startswith("@") || Sym.contains("@@") || Sym.startswith("?") ||
|
||||
(!MingwDef && Sym.contains('@'));
|
||||
}
|
||||
|
||||
static Error createError(const Twine &Err) {
|
||||
return make_error<StringError>(StringRef(Err.str()),
|
||||
object_error::parse_failed);
|
||||
}
|
||||
|
||||
class Lexer {
|
||||
public:
|
||||
Lexer(StringRef S) : Buf(S) {}
|
||||
|
||||
Token lex() {
|
||||
Buf = Buf.trim();
|
||||
if (Buf.empty())
|
||||
return Token(Eof);
|
||||
|
||||
switch (Buf[0]) {
|
||||
case '\0':
|
||||
return Token(Eof);
|
||||
case ';': {
|
||||
size_t End = Buf.find('\n');
|
||||
Buf = (End == Buf.npos) ? "" : Buf.drop_front(End);
|
||||
return lex();
|
||||
}
|
||||
case '=':
|
||||
Buf = Buf.drop_front();
|
||||
// GNU dlltool accepts both = and ==.
|
||||
if (Buf.startswith("="))
|
||||
Buf = Buf.drop_front();
|
||||
return Token(Equal, "=");
|
||||
case ',':
|
||||
Buf = Buf.drop_front();
|
||||
return Token(Comma, ",");
|
||||
case '"': {
|
||||
StringRef S;
|
||||
std::tie(S, Buf) = Buf.substr(1).split('"');
|
||||
return Token(Identifier, S);
|
||||
}
|
||||
default: {
|
||||
size_t End = Buf.find_first_of("=,;\r\n \t\v");
|
||||
StringRef Word = Buf.substr(0, End);
|
||||
Kind K = llvm::StringSwitch<Kind>(Word)
|
||||
.Case("BASE", KwBase)
|
||||
.Case("CONSTANT", KwConstant)
|
||||
.Case("DATA", KwData)
|
||||
.Case("EXPORTS", KwExports)
|
||||
.Case("HEAPSIZE", KwHeapsize)
|
||||
.Case("LIBRARY", KwLibrary)
|
||||
.Case("NAME", KwName)
|
||||
.Case("NONAME", KwNoname)
|
||||
.Case("PRIVATE", KwPrivate)
|
||||
.Case("STACKSIZE", KwStacksize)
|
||||
.Case("VERSION", KwVersion)
|
||||
.Default(Identifier);
|
||||
Buf = (End == Buf.npos) ? "" : Buf.drop_front(End);
|
||||
return Token(K, Word);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
StringRef Buf;
|
||||
};
|
||||
|
||||
class Parser {
|
||||
public:
|
||||
explicit Parser(StringRef S, MachineTypes M, bool B)
|
||||
: Lex(S), Machine(M), MingwDef(B) {}
|
||||
|
||||
Expected<COFFModuleDefinition> parse() {
|
||||
do {
|
||||
if (Error Err = parseOne())
|
||||
return std::move(Err);
|
||||
} while (Tok.K != Eof);
|
||||
return Info;
|
||||
}
|
||||
|
||||
private:
|
||||
void read() {
|
||||
if (Stack.empty()) {
|
||||
Tok = Lex.lex();
|
||||
return;
|
||||
}
|
||||
Tok = Stack.back();
|
||||
Stack.pop_back();
|
||||
}
|
||||
|
||||
Error readAsInt(uint64_t *I) {
|
||||
read();
|
||||
if (Tok.K != Identifier || Tok.Value.getAsInteger(10, *I))
|
||||
return createError("integer expected");
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error expect(Kind Expected, StringRef Msg) {
|
||||
read();
|
||||
if (Tok.K != Expected)
|
||||
return createError(Msg);
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
void unget() { Stack.push_back(Tok); }
|
||||
|
||||
Error parseOne() {
|
||||
read();
|
||||
switch (Tok.K) {
|
||||
case Eof:
|
||||
return Error::success();
|
||||
case KwExports:
|
||||
for (;;) {
|
||||
read();
|
||||
if (Tok.K != Identifier) {
|
||||
unget();
|
||||
return Error::success();
|
||||
}
|
||||
if (Error Err = parseExport())
|
||||
return Err;
|
||||
}
|
||||
case KwHeapsize:
|
||||
return parseNumbers(&Info.HeapReserve, &Info.HeapCommit);
|
||||
case KwStacksize:
|
||||
return parseNumbers(&Info.StackReserve, &Info.StackCommit);
|
||||
case KwLibrary:
|
||||
case KwName: {
|
||||
bool IsDll = Tok.K == KwLibrary; // Check before parseName.
|
||||
std::string Name;
|
||||
if (Error Err = parseName(&Name, &Info.ImageBase))
|
||||
return Err;
|
||||
|
||||
Info.ImportName = Name;
|
||||
|
||||
// Set the output file, but don't override /out if it was already passed.
|
||||
if (Info.OutputFile.empty()) {
|
||||
Info.OutputFile = Name;
|
||||
// Append the appropriate file extension if not already present.
|
||||
if (!sys::path::has_extension(Name))
|
||||
Info.OutputFile += IsDll ? ".dll" : ".exe";
|
||||
}
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
case KwVersion:
|
||||
return parseVersion(&Info.MajorImageVersion, &Info.MinorImageVersion);
|
||||
default:
|
||||
return createError("unknown directive: " + Tok.Value);
|
||||
}
|
||||
}
|
||||
|
||||
Error parseExport() {
|
||||
COFFShortExport E;
|
||||
E.Name = Tok.Value;
|
||||
read();
|
||||
if (Tok.K == Equal) {
|
||||
read();
|
||||
if (Tok.K != Identifier)
|
||||
return createError("identifier expected, but got " + Tok.Value);
|
||||
E.ExtName = E.Name;
|
||||
E.Name = Tok.Value;
|
||||
} else {
|
||||
unget();
|
||||
}
|
||||
|
||||
if (Machine == IMAGE_FILE_MACHINE_I386) {
|
||||
if (!isDecorated(E.Name, MingwDef))
|
||||
E.Name = (std::string("_").append(E.Name));
|
||||
if (!E.ExtName.empty() && !isDecorated(E.ExtName, MingwDef))
|
||||
E.ExtName = (std::string("_").append(E.ExtName));
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
read();
|
||||
if (Tok.K == Identifier && Tok.Value[0] == '@') {
|
||||
if (Tok.Value == "@") {
|
||||
// "foo @ 10"
|
||||
read();
|
||||
Tok.Value.getAsInteger(10, E.Ordinal);
|
||||
} else if (Tok.Value.drop_front().getAsInteger(10, E.Ordinal)) {
|
||||
// "foo \n @bar" - Not an ordinal modifier at all, but the next
|
||||
// export (fastcall decorated) - complete the current one.
|
||||
unget();
|
||||
Info.Exports.push_back(E);
|
||||
return Error::success();
|
||||
}
|
||||
// "foo @10"
|
||||
read();
|
||||
if (Tok.K == KwNoname) {
|
||||
E.Noname = true;
|
||||
} else {
|
||||
unget();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (Tok.K == KwData) {
|
||||
E.Data = true;
|
||||
continue;
|
||||
}
|
||||
if (Tok.K == KwConstant) {
|
||||
E.Constant = true;
|
||||
continue;
|
||||
}
|
||||
if (Tok.K == KwPrivate) {
|
||||
E.Private = true;
|
||||
continue;
|
||||
}
|
||||
unget();
|
||||
Info.Exports.push_back(E);
|
||||
return Error::success();
|
||||
}
|
||||
}
|
||||
|
||||
// HEAPSIZE/STACKSIZE reserve[,commit]
|
||||
Error parseNumbers(uint64_t *Reserve, uint64_t *Commit) {
|
||||
if (Error Err = readAsInt(Reserve))
|
||||
return Err;
|
||||
read();
|
||||
if (Tok.K != Comma) {
|
||||
unget();
|
||||
Commit = nullptr;
|
||||
return Error::success();
|
||||
}
|
||||
if (Error Err = readAsInt(Commit))
|
||||
return Err;
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
// NAME outputPath [BASE=address]
|
||||
Error parseName(std::string *Out, uint64_t *Baseaddr) {
|
||||
read();
|
||||
if (Tok.K == Identifier) {
|
||||
*Out = Tok.Value;
|
||||
} else {
|
||||
*Out = "";
|
||||
unget();
|
||||
return Error::success();
|
||||
}
|
||||
read();
|
||||
if (Tok.K == KwBase) {
|
||||
if (Error Err = expect(Equal, "'=' expected"))
|
||||
return Err;
|
||||
if (Error Err = readAsInt(Baseaddr))
|
||||
return Err;
|
||||
} else {
|
||||
unget();
|
||||
*Baseaddr = 0;
|
||||
}
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
// VERSION major[.minor]
|
||||
Error parseVersion(uint32_t *Major, uint32_t *Minor) {
|
||||
read();
|
||||
if (Tok.K != Identifier)
|
||||
return createError("identifier expected, but got " + Tok.Value);
|
||||
StringRef V1, V2;
|
||||
std::tie(V1, V2) = Tok.Value.split('.');
|
||||
if (V1.getAsInteger(10, *Major))
|
||||
return createError("integer expected, but got " + Tok.Value);
|
||||
if (V2.empty())
|
||||
*Minor = 0;
|
||||
else if (V2.getAsInteger(10, *Minor))
|
||||
return createError("integer expected, but got " + Tok.Value);
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Lexer Lex;
|
||||
Token Tok;
|
||||
std::vector<Token> Stack;
|
||||
MachineTypes Machine;
|
||||
COFFModuleDefinition Info;
|
||||
bool MingwDef;
|
||||
};
|
||||
|
||||
Expected<COFFModuleDefinition> parseCOFFModuleDefinition(MemoryBufferRef MB,
|
||||
MachineTypes Machine,
|
||||
bool MingwDef) {
|
||||
return Parser(MB.getBuffer(), Machine, MingwDef).parse();
|
||||
}
|
||||
|
||||
} // namespace object
|
||||
} // namespace llvm
|
1674
external/llvm/lib/Object/COFFObjectFile.cpp
vendored
1674
external/llvm/lib/Object/COFFObjectFile.cpp
vendored
File diff suppressed because it is too large
Load Diff
94
external/llvm/lib/Object/Decompressor.cpp
vendored
94
external/llvm/lib/Object/Decompressor.cpp
vendored
@ -1,94 +0,0 @@
|
||||
//===-- Decompressor.cpp --------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Object/Decompressor.h"
|
||||
#include "llvm/BinaryFormat/ELF.h"
|
||||
#include "llvm/Object/ELFObjectFile.h"
|
||||
#include "llvm/Support/Compression.h"
|
||||
#include "llvm/Support/DataExtractor.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::support::endian;
|
||||
using namespace object;
|
||||
|
||||
Expected<Decompressor> Decompressor::create(StringRef Name, StringRef Data,
|
||||
bool IsLE, bool Is64Bit) {
|
||||
if (!zlib::isAvailable())
|
||||
return createError("zlib is not available");
|
||||
|
||||
Decompressor D(Data);
|
||||
Error Err = isGnuStyle(Name) ? D.consumeCompressedGnuHeader()
|
||||
: D.consumeCompressedZLibHeader(Is64Bit, IsLE);
|
||||
if (Err)
|
||||
return std::move(Err);
|
||||
return D;
|
||||
}
|
||||
|
||||
Decompressor::Decompressor(StringRef Data)
|
||||
: SectionData(Data), DecompressedSize(0) {}
|
||||
|
||||
Error Decompressor::consumeCompressedGnuHeader() {
|
||||
if (!SectionData.startswith("ZLIB"))
|
||||
return createError("corrupted compressed section header");
|
||||
|
||||
SectionData = SectionData.substr(4);
|
||||
|
||||
// Consume uncompressed section size (big-endian 8 bytes).
|
||||
if (SectionData.size() < 8)
|
||||
return createError("corrupted uncompressed section size");
|
||||
DecompressedSize = read64be(SectionData.data());
|
||||
SectionData = SectionData.substr(8);
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error Decompressor::consumeCompressedZLibHeader(bool Is64Bit,
|
||||
bool IsLittleEndian) {
|
||||
using namespace ELF;
|
||||
uint64_t HdrSize = Is64Bit ? sizeof(Elf64_Chdr) : sizeof(Elf32_Chdr);
|
||||
if (SectionData.size() < HdrSize)
|
||||
return createError("corrupted compressed section header");
|
||||
|
||||
DataExtractor Extractor(SectionData, IsLittleEndian, 0);
|
||||
uint32_t Offset = 0;
|
||||
if (Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Word)
|
||||
: sizeof(Elf32_Word)) !=
|
||||
ELFCOMPRESS_ZLIB)
|
||||
return createError("unsupported compression type");
|
||||
|
||||
// Skip Elf64_Chdr::ch_reserved field.
|
||||
if (Is64Bit)
|
||||
Offset += sizeof(Elf64_Word);
|
||||
|
||||
DecompressedSize = Extractor.getUnsigned(
|
||||
&Offset, Is64Bit ? sizeof(Elf64_Xword) : sizeof(Elf32_Word));
|
||||
SectionData = SectionData.substr(HdrSize);
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
bool Decompressor::isGnuStyle(StringRef Name) {
|
||||
return Name.startswith(".zdebug");
|
||||
}
|
||||
|
||||
bool Decompressor::isCompressed(const object::SectionRef &Section) {
|
||||
StringRef Name;
|
||||
if (Section.getName(Name))
|
||||
return false;
|
||||
return Section.isCompressed() || isGnuStyle(Name);
|
||||
}
|
||||
|
||||
bool Decompressor::isCompressedELFSection(uint64_t Flags, StringRef Name) {
|
||||
return (Flags & ELF::SHF_COMPRESSED) || isGnuStyle(Name);
|
||||
}
|
||||
|
||||
Error Decompressor::decompress(MutableArrayRef<char> Buffer) {
|
||||
size_t Size = Buffer.size();
|
||||
return zlib::uncompress(SectionData, Buffer.data(), Size);
|
||||
}
|
305
external/llvm/lib/Object/ELF.cpp
vendored
305
external/llvm/lib/Object/ELF.cpp
vendored
@ -1,305 +0,0 @@
|
||||
//===- ELF.cpp - ELF object file implementation ---------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Object/ELF.h"
|
||||
#include "llvm/BinaryFormat/ELF.h"
|
||||
#include "llvm/Support/LEB128.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace object;
|
||||
|
||||
#define STRINGIFY_ENUM_CASE(ns, name) \
|
||||
case ns::name: \
|
||||
return #name;
|
||||
|
||||
#define ELF_RELOC(name, value) STRINGIFY_ENUM_CASE(ELF, name)
|
||||
|
||||
StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine,
|
||||
uint32_t Type) {
|
||||
switch (Machine) {
|
||||
case ELF::EM_X86_64:
|
||||
switch (Type) {
|
||||
#include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_386:
|
||||
case ELF::EM_IAMCU:
|
||||
switch (Type) {
|
||||
#include "llvm/BinaryFormat/ELFRelocs/i386.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_MIPS:
|
||||
switch (Type) {
|
||||
#include "llvm/BinaryFormat/ELFRelocs/Mips.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_AARCH64:
|
||||
switch (Type) {
|
||||
#include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_ARM:
|
||||
switch (Type) {
|
||||
#include "llvm/BinaryFormat/ELFRelocs/ARM.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_ARC_COMPACT:
|
||||
case ELF::EM_ARC_COMPACT2:
|
||||
switch (Type) {
|
||||
#include "llvm/BinaryFormat/ELFRelocs/ARC.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_AVR:
|
||||
switch (Type) {
|
||||
#include "llvm/BinaryFormat/ELFRelocs/AVR.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_HEXAGON:
|
||||
switch (Type) {
|
||||
#include "llvm/BinaryFormat/ELFRelocs/Hexagon.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_LANAI:
|
||||
switch (Type) {
|
||||
#include "llvm/BinaryFormat/ELFRelocs/Lanai.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_PPC:
|
||||
switch (Type) {
|
||||
#include "llvm/BinaryFormat/ELFRelocs/PowerPC.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_PPC64:
|
||||
switch (Type) {
|
||||
#include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_RISCV:
|
||||
switch (Type) {
|
||||
#include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_S390:
|
||||
switch (Type) {
|
||||
#include "llvm/BinaryFormat/ELFRelocs/SystemZ.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_SPARC:
|
||||
case ELF::EM_SPARC32PLUS:
|
||||
case ELF::EM_SPARCV9:
|
||||
switch (Type) {
|
||||
#include "llvm/BinaryFormat/ELFRelocs/Sparc.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_WEBASSEMBLY:
|
||||
switch (Type) {
|
||||
#include "llvm/BinaryFormat/ELFRelocs/WebAssembly.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_AMDGPU:
|
||||
switch (Type) {
|
||||
#include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ELF::EM_BPF:
|
||||
switch (Type) {
|
||||
#include "llvm/BinaryFormat/ELFRelocs/BPF.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
#undef ELF_RELOC
|
||||
|
||||
StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {
|
||||
switch (Machine) {
|
||||
case ELF::EM_ARM:
|
||||
switch (Type) {
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_ARM_EXIDX);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION);
|
||||
}
|
||||
break;
|
||||
case ELF::EM_HEXAGON:
|
||||
switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED); }
|
||||
break;
|
||||
case ELF::EM_X86_64:
|
||||
switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_X86_64_UNWIND); }
|
||||
break;
|
||||
case ELF::EM_MIPS:
|
||||
case ELF::EM_MIPS_RS3_LE:
|
||||
switch (Type) {
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_REGINFO);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_OPTIONS);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_DWARF);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Type) {
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_NULL);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_PROGBITS);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_STRTAB);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_RELA);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_HASH);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_DYNAMIC);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_NOTE);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_NOBITS);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_REL);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_SHLIB);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_DYNSYM);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_INIT_ARRAY);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_FINI_ARRAY);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_PREINIT_ARRAY);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_GROUP);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_REL);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELA);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ODRTAB);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verneed);
|
||||
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_versym);
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
Expected<std::vector<typename ELFT::Rela>>
|
||||
ELFFile<ELFT>::android_relas(const Elf_Shdr *Sec) const {
|
||||
// This function reads relocations in Android's packed relocation format,
|
||||
// which is based on SLEB128 and delta encoding.
|
||||
Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
|
||||
if (!ContentsOrErr)
|
||||
return ContentsOrErr.takeError();
|
||||
const uint8_t *Cur = ContentsOrErr->begin();
|
||||
const uint8_t *End = ContentsOrErr->end();
|
||||
if (ContentsOrErr->size() < 4 || Cur[0] != 'A' || Cur[1] != 'P' ||
|
||||
Cur[2] != 'S' || Cur[3] != '2')
|
||||
return createError("invalid packed relocation header");
|
||||
Cur += 4;
|
||||
|
||||
const char *ErrStr = nullptr;
|
||||
auto ReadSLEB = [&]() -> int64_t {
|
||||
if (ErrStr)
|
||||
return 0;
|
||||
unsigned Len;
|
||||
int64_t Result = decodeSLEB128(Cur, &Len, End, &ErrStr);
|
||||
Cur += Len;
|
||||
return Result;
|
||||
};
|
||||
|
||||
uint64_t NumRelocs = ReadSLEB();
|
||||
uint64_t Offset = ReadSLEB();
|
||||
uint64_t Addend = 0;
|
||||
|
||||
if (ErrStr)
|
||||
return createError(ErrStr);
|
||||
|
||||
std::vector<Elf_Rela> Relocs;
|
||||
Relocs.reserve(NumRelocs);
|
||||
while (NumRelocs) {
|
||||
uint64_t NumRelocsInGroup = ReadSLEB();
|
||||
if (NumRelocsInGroup > NumRelocs)
|
||||
return createError("relocation group unexpectedly large");
|
||||
NumRelocs -= NumRelocsInGroup;
|
||||
|
||||
uint64_t GroupFlags = ReadSLEB();
|
||||
bool GroupedByInfo = GroupFlags & ELF::RELOCATION_GROUPED_BY_INFO_FLAG;
|
||||
bool GroupedByOffsetDelta = GroupFlags & ELF::RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG;
|
||||
bool GroupedByAddend = GroupFlags & ELF::RELOCATION_GROUPED_BY_ADDEND_FLAG;
|
||||
bool GroupHasAddend = GroupFlags & ELF::RELOCATION_GROUP_HAS_ADDEND_FLAG;
|
||||
|
||||
uint64_t GroupOffsetDelta;
|
||||
if (GroupedByOffsetDelta)
|
||||
GroupOffsetDelta = ReadSLEB();
|
||||
|
||||
uint64_t GroupRInfo;
|
||||
if (GroupedByInfo)
|
||||
GroupRInfo = ReadSLEB();
|
||||
|
||||
if (GroupedByAddend && GroupHasAddend)
|
||||
Addend += ReadSLEB();
|
||||
|
||||
for (uint64_t I = 0; I != NumRelocsInGroup; ++I) {
|
||||
Elf_Rela R;
|
||||
Offset += GroupedByOffsetDelta ? GroupOffsetDelta : ReadSLEB();
|
||||
R.r_offset = Offset;
|
||||
R.r_info = GroupedByInfo ? GroupRInfo : ReadSLEB();
|
||||
|
||||
if (GroupHasAddend) {
|
||||
if (!GroupedByAddend)
|
||||
Addend += ReadSLEB();
|
||||
R.r_addend = Addend;
|
||||
} else {
|
||||
R.r_addend = 0;
|
||||
}
|
||||
|
||||
Relocs.push_back(R);
|
||||
|
||||
if (ErrStr)
|
||||
return createError(ErrStr);
|
||||
}
|
||||
|
||||
if (ErrStr)
|
||||
return createError(ErrStr);
|
||||
}
|
||||
|
||||
return Relocs;
|
||||
}
|
||||
|
||||
template class llvm::object::ELFFile<ELF32LE>;
|
||||
template class llvm::object::ELFFile<ELF32BE>;
|
||||
template class llvm::object::ELFFile<ELF64LE>;
|
||||
template class llvm::object::ELFFile<ELF64BE>;
|
317
external/llvm/lib/Object/ELFObjectFile.cpp
vendored
317
external/llvm/lib/Object/ELFObjectFile.cpp
vendored
@ -1,317 +0,0 @@
|
||||
//===- ELFObjectFile.cpp - ELF object file implementation -----------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the ELFObjectFile class implementation.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Object/ELFObjectFile.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/BinaryFormat/ELF.h"
|
||||
#include "llvm/MC/SubtargetFeature.h"
|
||||
#include "llvm/Object/ELF.h"
|
||||
#include "llvm/Object/ELFTypes.h"
|
||||
#include "llvm/Object/Error.h"
|
||||
#include "llvm/Support/ARMAttributeParser.h"
|
||||
#include "llvm/Support/ARMBuildAttributes.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
#include <utility>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace object;
|
||||
|
||||
ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
|
||||
: ObjectFile(Type, Source) {}
|
||||
|
||||
template <class ELFT>
|
||||
static Expected<std::unique_ptr<ELFObjectFile<ELFT>>>
|
||||
createPtr(MemoryBufferRef Object) {
|
||||
auto Ret = ELFObjectFile<ELFT>::create(Object);
|
||||
if (Error E = Ret.takeError())
|
||||
return std::move(E);
|
||||
return make_unique<ELFObjectFile<ELFT>>(std::move(*Ret));
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<ObjectFile>>
|
||||
ObjectFile::createELFObjectFile(MemoryBufferRef Obj) {
|
||||
std::pair<unsigned char, unsigned char> Ident =
|
||||
getElfArchType(Obj.getBuffer());
|
||||
std::size_t MaxAlignment =
|
||||
1ULL << countTrailingZeros(uintptr_t(Obj.getBufferStart()));
|
||||
|
||||
if (MaxAlignment < 2)
|
||||
return createError("Insufficient alignment");
|
||||
|
||||
if (Ident.first == ELF::ELFCLASS32) {
|
||||
if (Ident.second == ELF::ELFDATA2LSB)
|
||||
return createPtr<ELF32LE>(Obj);
|
||||
else if (Ident.second == ELF::ELFDATA2MSB)
|
||||
return createPtr<ELF32BE>(Obj);
|
||||
else
|
||||
return createError("Invalid ELF data");
|
||||
} else if (Ident.first == ELF::ELFCLASS64) {
|
||||
if (Ident.second == ELF::ELFDATA2LSB)
|
||||
return createPtr<ELF64LE>(Obj);
|
||||
else if (Ident.second == ELF::ELFDATA2MSB)
|
||||
return createPtr<ELF64BE>(Obj);
|
||||
else
|
||||
return createError("Invalid ELF data");
|
||||
}
|
||||
return createError("Invalid ELF class");
|
||||
}
|
||||
|
||||
SubtargetFeatures ELFObjectFileBase::getMIPSFeatures() const {
|
||||
SubtargetFeatures Features;
|
||||
unsigned PlatformFlags;
|
||||
getPlatformFlags(PlatformFlags);
|
||||
|
||||
switch (PlatformFlags & ELF::EF_MIPS_ARCH) {
|
||||
case ELF::EF_MIPS_ARCH_1:
|
||||
break;
|
||||
case ELF::EF_MIPS_ARCH_2:
|
||||
Features.AddFeature("mips2");
|
||||
break;
|
||||
case ELF::EF_MIPS_ARCH_3:
|
||||
Features.AddFeature("mips3");
|
||||
break;
|
||||
case ELF::EF_MIPS_ARCH_4:
|
||||
Features.AddFeature("mips4");
|
||||
break;
|
||||
case ELF::EF_MIPS_ARCH_5:
|
||||
Features.AddFeature("mips5");
|
||||
break;
|
||||
case ELF::EF_MIPS_ARCH_32:
|
||||
Features.AddFeature("mips32");
|
||||
break;
|
||||
case ELF::EF_MIPS_ARCH_64:
|
||||
Features.AddFeature("mips64");
|
||||
break;
|
||||
case ELF::EF_MIPS_ARCH_32R2:
|
||||
Features.AddFeature("mips32r2");
|
||||
break;
|
||||
case ELF::EF_MIPS_ARCH_64R2:
|
||||
Features.AddFeature("mips64r2");
|
||||
break;
|
||||
case ELF::EF_MIPS_ARCH_32R6:
|
||||
Features.AddFeature("mips32r6");
|
||||
break;
|
||||
case ELF::EF_MIPS_ARCH_64R6:
|
||||
Features.AddFeature("mips64r6");
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unknown EF_MIPS_ARCH value");
|
||||
}
|
||||
|
||||
switch (PlatformFlags & ELF::EF_MIPS_MACH) {
|
||||
case ELF::EF_MIPS_MACH_NONE:
|
||||
// No feature associated with this value.
|
||||
break;
|
||||
case ELF::EF_MIPS_MACH_OCTEON:
|
||||
Features.AddFeature("cnmips");
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unknown EF_MIPS_ARCH value");
|
||||
}
|
||||
|
||||
if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16)
|
||||
Features.AddFeature("mips16");
|
||||
if (PlatformFlags & ELF::EF_MIPS_MICROMIPS)
|
||||
Features.AddFeature("micromips");
|
||||
|
||||
return Features;
|
||||
}
|
||||
|
||||
SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
|
||||
SubtargetFeatures Features;
|
||||
ARMAttributeParser Attributes;
|
||||
std::error_code EC = getBuildAttributes(Attributes);
|
||||
if (EC)
|
||||
return SubtargetFeatures();
|
||||
|
||||
// both ARMv7-M and R have to support thumb hardware div
|
||||
bool isV7 = false;
|
||||
if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch))
|
||||
isV7 = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)
|
||||
== ARMBuildAttrs::v7;
|
||||
|
||||
if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch_profile)) {
|
||||
switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile)) {
|
||||
case ARMBuildAttrs::ApplicationProfile:
|
||||
Features.AddFeature("aclass");
|
||||
break;
|
||||
case ARMBuildAttrs::RealTimeProfile:
|
||||
Features.AddFeature("rclass");
|
||||
if (isV7)
|
||||
Features.AddFeature("hwdiv");
|
||||
break;
|
||||
case ARMBuildAttrs::MicroControllerProfile:
|
||||
Features.AddFeature("mclass");
|
||||
if (isV7)
|
||||
Features.AddFeature("hwdiv");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Attributes.hasAttribute(ARMBuildAttrs::THUMB_ISA_use)) {
|
||||
switch(Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use)) {
|
||||
default:
|
||||
break;
|
||||
case ARMBuildAttrs::Not_Allowed:
|
||||
Features.AddFeature("thumb", false);
|
||||
Features.AddFeature("thumb2", false);
|
||||
break;
|
||||
case ARMBuildAttrs::AllowThumb32:
|
||||
Features.AddFeature("thumb2");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Attributes.hasAttribute(ARMBuildAttrs::FP_arch)) {
|
||||
switch(Attributes.getAttributeValue(ARMBuildAttrs::FP_arch)) {
|
||||
default:
|
||||
break;
|
||||
case ARMBuildAttrs::Not_Allowed:
|
||||
Features.AddFeature("vfp2", false);
|
||||
Features.AddFeature("vfp3", false);
|
||||
Features.AddFeature("vfp4", false);
|
||||
break;
|
||||
case ARMBuildAttrs::AllowFPv2:
|
||||
Features.AddFeature("vfp2");
|
||||
break;
|
||||
case ARMBuildAttrs::AllowFPv3A:
|
||||
case ARMBuildAttrs::AllowFPv3B:
|
||||
Features.AddFeature("vfp3");
|
||||
break;
|
||||
case ARMBuildAttrs::AllowFPv4A:
|
||||
case ARMBuildAttrs::AllowFPv4B:
|
||||
Features.AddFeature("vfp4");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Attributes.hasAttribute(ARMBuildAttrs::Advanced_SIMD_arch)) {
|
||||
switch(Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch)) {
|
||||
default:
|
||||
break;
|
||||
case ARMBuildAttrs::Not_Allowed:
|
||||
Features.AddFeature("neon", false);
|
||||
Features.AddFeature("fp16", false);
|
||||
break;
|
||||
case ARMBuildAttrs::AllowNeon:
|
||||
Features.AddFeature("neon");
|
||||
break;
|
||||
case ARMBuildAttrs::AllowNeon2:
|
||||
Features.AddFeature("neon");
|
||||
Features.AddFeature("fp16");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Attributes.hasAttribute(ARMBuildAttrs::DIV_use)) {
|
||||
switch(Attributes.getAttributeValue(ARMBuildAttrs::DIV_use)) {
|
||||
default:
|
||||
break;
|
||||
case ARMBuildAttrs::DisallowDIV:
|
||||
Features.AddFeature("hwdiv", false);
|
||||
Features.AddFeature("hwdiv-arm", false);
|
||||
break;
|
||||
case ARMBuildAttrs::AllowDIVExt:
|
||||
Features.AddFeature("hwdiv");
|
||||
Features.AddFeature("hwdiv-arm");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Features;
|
||||
}
|
||||
|
||||
SubtargetFeatures ELFObjectFileBase::getFeatures() const {
|
||||
switch (getEMachine()) {
|
||||
case ELF::EM_MIPS:
|
||||
return getMIPSFeatures();
|
||||
case ELF::EM_ARM:
|
||||
return getARMFeatures();
|
||||
default:
|
||||
return SubtargetFeatures();
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME Encode from a tablegen description or target parser.
|
||||
void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
|
||||
if (TheTriple.getSubArch() != Triple::NoSubArch)
|
||||
return;
|
||||
|
||||
ARMAttributeParser Attributes;
|
||||
std::error_code EC = getBuildAttributes(Attributes);
|
||||
if (EC)
|
||||
return;
|
||||
|
||||
std::string Triple;
|
||||
// Default to ARM, but use the triple if it's been set.
|
||||
if (TheTriple.isThumb())
|
||||
Triple = "thumb";
|
||||
else
|
||||
Triple = "arm";
|
||||
|
||||
if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) {
|
||||
switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)) {
|
||||
case ARMBuildAttrs::v4:
|
||||
Triple += "v4";
|
||||
break;
|
||||
case ARMBuildAttrs::v4T:
|
||||
Triple += "v4t";
|
||||
break;
|
||||
case ARMBuildAttrs::v5T:
|
||||
Triple += "v5t";
|
||||
break;
|
||||
case ARMBuildAttrs::v5TE:
|
||||
Triple += "v5te";
|
||||
break;
|
||||
case ARMBuildAttrs::v5TEJ:
|
||||
Triple += "v5tej";
|
||||
break;
|
||||
case ARMBuildAttrs::v6:
|
||||
Triple += "v6";
|
||||
break;
|
||||
case ARMBuildAttrs::v6KZ:
|
||||
Triple += "v6kz";
|
||||
break;
|
||||
case ARMBuildAttrs::v6T2:
|
||||
Triple += "v6t2";
|
||||
break;
|
||||
case ARMBuildAttrs::v6K:
|
||||
Triple += "v6k";
|
||||
break;
|
||||
case ARMBuildAttrs::v7:
|
||||
Triple += "v7";
|
||||
break;
|
||||
case ARMBuildAttrs::v6_M:
|
||||
Triple += "v6m";
|
||||
break;
|
||||
case ARMBuildAttrs::v6S_M:
|
||||
Triple += "v6sm";
|
||||
break;
|
||||
case ARMBuildAttrs::v7E_M:
|
||||
Triple += "v7em";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isLittleEndian())
|
||||
Triple += "eb";
|
||||
|
||||
TheTriple.setArchName(Triple);
|
||||
}
|
95
external/llvm/lib/Object/Error.cpp
vendored
95
external/llvm/lib/Object/Error.cpp
vendored
@ -1,95 +0,0 @@
|
||||
//===- Error.cpp - system_error extensions for Object -----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This defines a new error_category for the Object library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Object/Error.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace object;
|
||||
|
||||
namespace {
|
||||
// FIXME: This class is only here to support the transition to llvm::Error. It
|
||||
// will be removed once this transition is complete. Clients should prefer to
|
||||
// deal with the Error value directly, rather than converting to error_code.
|
||||
class _object_error_category : public std::error_category {
|
||||
public:
|
||||
const char* name() const noexcept override;
|
||||
std::string message(int ev) const override;
|
||||
};
|
||||
}
|
||||
|
||||
const char *_object_error_category::name() const noexcept {
|
||||
return "llvm.object";
|
||||
}
|
||||
|
||||
std::string _object_error_category::message(int EV) const {
|
||||
object_error E = static_cast<object_error>(EV);
|
||||
switch (E) {
|
||||
case object_error::arch_not_found:
|
||||
return "No object file for requested architecture";
|
||||
case object_error::invalid_file_type:
|
||||
return "The file was not recognized as a valid object file";
|
||||
case object_error::parse_failed:
|
||||
return "Invalid data was encountered while parsing the file";
|
||||
case object_error::unexpected_eof:
|
||||
return "The end of the file was unexpectedly encountered";
|
||||
case object_error::string_table_non_null_end:
|
||||
return "String table must end with a null terminator";
|
||||
case object_error::invalid_section_index:
|
||||
return "Invalid section index";
|
||||
case object_error::bitcode_section_not_found:
|
||||
return "Bitcode section not found in object file";
|
||||
case object_error::invalid_symbol_index:
|
||||
return "Invalid symbol index";
|
||||
}
|
||||
llvm_unreachable("An enumerator of object_error does not have a message "
|
||||
"defined.");
|
||||
}
|
||||
|
||||
char BinaryError::ID = 0;
|
||||
char GenericBinaryError::ID = 0;
|
||||
|
||||
GenericBinaryError::GenericBinaryError(Twine Msg) : Msg(Msg.str()) {}
|
||||
|
||||
GenericBinaryError::GenericBinaryError(Twine Msg, object_error ECOverride)
|
||||
: Msg(Msg.str()) {
|
||||
setErrorCode(make_error_code(ECOverride));
|
||||
}
|
||||
|
||||
void GenericBinaryError::log(raw_ostream &OS) const {
|
||||
OS << Msg;
|
||||
}
|
||||
|
||||
static ManagedStatic<_object_error_category> error_category;
|
||||
|
||||
const std::error_category &object::object_category() {
|
||||
return *error_category;
|
||||
}
|
||||
|
||||
llvm::Error llvm::object::isNotObjectErrorInvalidFileType(llvm::Error Err) {
|
||||
if (auto Err2 =
|
||||
handleErrors(std::move(Err), [](std::unique_ptr<ECError> M) -> Error {
|
||||
// Try to handle 'M'. If successful, return a success value from
|
||||
// the handler.
|
||||
if (M->convertToErrorCode() == object_error::invalid_file_type)
|
||||
return Error::success();
|
||||
|
||||
// We failed to handle 'M' - return it from the handler.
|
||||
// This value will be passed back from catchErrors and
|
||||
// wind up in Err2, where it will be returned from this function.
|
||||
return Error(std::move(M));
|
||||
}))
|
||||
return Err2;
|
||||
return Err;
|
||||
}
|
155
external/llvm/lib/Object/IRObjectFile.cpp
vendored
155
external/llvm/lib/Object/IRObjectFile.cpp
vendored
@ -1,155 +0,0 @@
|
||||
//===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the IRObjectFile class implementation.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Object/IRObjectFile.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/BinaryFormat/Magic.h"
|
||||
#include "llvm/Bitcode/BitcodeReader.h"
|
||||
#include "llvm/IR/GVMaterializer.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
using namespace object;
|
||||
|
||||
IRObjectFile::IRObjectFile(MemoryBufferRef Object,
|
||||
std::vector<std::unique_ptr<Module>> Mods)
|
||||
: SymbolicFile(Binary::ID_IR, Object), Mods(std::move(Mods)) {
|
||||
for (auto &M : this->Mods)
|
||||
SymTab.addModule(M.get());
|
||||
}
|
||||
|
||||
IRObjectFile::~IRObjectFile() {}
|
||||
|
||||
static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) {
|
||||
return *reinterpret_cast<ModuleSymbolTable::Symbol *>(Symb.p);
|
||||
}
|
||||
|
||||
void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
|
||||
Symb.p += sizeof(ModuleSymbolTable::Symbol);
|
||||
}
|
||||
|
||||
std::error_code IRObjectFile::printSymbolName(raw_ostream &OS,
|
||||
DataRefImpl Symb) const {
|
||||
SymTab.printSymbolName(OS, getSym(Symb));
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
|
||||
return SymTab.getSymbolFlags(getSym(Symb));
|
||||
}
|
||||
|
||||
basic_symbol_iterator IRObjectFile::symbol_begin() const {
|
||||
DataRefImpl Ret;
|
||||
Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data());
|
||||
return basic_symbol_iterator(BasicSymbolRef(Ret, this));
|
||||
}
|
||||
|
||||
basic_symbol_iterator IRObjectFile::symbol_end() const {
|
||||
DataRefImpl Ret;
|
||||
Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data() +
|
||||
SymTab.symbols().size());
|
||||
return basic_symbol_iterator(BasicSymbolRef(Ret, this));
|
||||
}
|
||||
|
||||
StringRef IRObjectFile::getTargetTriple() const {
|
||||
// Each module must have the same target triple, so we arbitrarily access the
|
||||
// first one.
|
||||
return Mods[0]->getTargetTriple();
|
||||
}
|
||||
|
||||
Expected<MemoryBufferRef>
|
||||
IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
|
||||
for (const SectionRef &Sec : Obj.sections()) {
|
||||
if (Sec.isBitcode()) {
|
||||
StringRef SecContents;
|
||||
if (std::error_code EC = Sec.getContents(SecContents))
|
||||
return errorCodeToError(EC);
|
||||
return MemoryBufferRef(SecContents, Obj.getFileName());
|
||||
}
|
||||
}
|
||||
|
||||
return errorCodeToError(object_error::bitcode_section_not_found);
|
||||
}
|
||||
|
||||
Expected<MemoryBufferRef>
|
||||
IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
|
||||
file_magic Type = identify_magic(Object.getBuffer());
|
||||
switch (Type) {
|
||||
case file_magic::bitcode:
|
||||
return Object;
|
||||
case file_magic::elf_relocatable:
|
||||
case file_magic::macho_object:
|
||||
case file_magic::coff_object: {
|
||||
Expected<std::unique_ptr<ObjectFile>> ObjFile =
|
||||
ObjectFile::createObjectFile(Object, Type);
|
||||
if (!ObjFile)
|
||||
return ObjFile.takeError();
|
||||
return findBitcodeInObject(*ObjFile->get());
|
||||
}
|
||||
default:
|
||||
return errorCodeToError(object_error::invalid_file_type);
|
||||
}
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<IRObjectFile>>
|
||||
IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) {
|
||||
Expected<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
|
||||
if (!BCOrErr)
|
||||
return BCOrErr.takeError();
|
||||
|
||||
Expected<std::vector<BitcodeModule>> BMsOrErr =
|
||||
getBitcodeModuleList(*BCOrErr);
|
||||
if (!BMsOrErr)
|
||||
return BMsOrErr.takeError();
|
||||
|
||||
std::vector<std::unique_ptr<Module>> Mods;
|
||||
for (auto BM : *BMsOrErr) {
|
||||
Expected<std::unique_ptr<Module>> MOrErr =
|
||||
BM.getLazyModule(Context, /*ShouldLazyLoadMetadata*/ true,
|
||||
/*IsImporting*/ false);
|
||||
if (!MOrErr)
|
||||
return MOrErr.takeError();
|
||||
|
||||
Mods.push_back(std::move(*MOrErr));
|
||||
}
|
||||
|
||||
return std::unique_ptr<IRObjectFile>(
|
||||
new IRObjectFile(*BCOrErr, std::move(Mods)));
|
||||
}
|
||||
|
||||
Expected<IRSymtabFile> object::readIRSymtab(MemoryBufferRef MBRef) {
|
||||
IRSymtabFile F;
|
||||
Expected<MemoryBufferRef> BCOrErr =
|
||||
IRObjectFile::findBitcodeInMemBuffer(MBRef);
|
||||
if (!BCOrErr)
|
||||
return BCOrErr.takeError();
|
||||
|
||||
Expected<BitcodeFileContents> BFCOrErr = getBitcodeFileContents(*BCOrErr);
|
||||
if (!BFCOrErr)
|
||||
return BFCOrErr.takeError();
|
||||
|
||||
Expected<irsymtab::FileContents> FCOrErr = irsymtab::readBitcode(*BFCOrErr);
|
||||
if (!FCOrErr)
|
||||
return FCOrErr.takeError();
|
||||
|
||||
F.Mods = std::move(BFCOrErr->Mods);
|
||||
F.Symtab = std::move(FCOrErr->Symtab);
|
||||
F.Strtab = std::move(FCOrErr->Strtab);
|
||||
F.TheReader = std::move(FCOrErr->TheReader);
|
||||
return std::move(F);
|
||||
}
|
382
external/llvm/lib/Object/IRSymtab.cpp
vendored
382
external/llvm/lib/Object/IRSymtab.cpp
vendored
@ -1,382 +0,0 @@
|
||||
//===- IRSymtab.cpp - implementation of IR symbol tables ------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Object/IRSymtab.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Analysis/ObjectUtils.h"
|
||||
#include "llvm/IR/Comdat.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/GlobalAlias.h"
|
||||
#include "llvm/IR/GlobalObject.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Bitcode/BitcodeReader.h"
|
||||
#include "llvm/MC/StringTableBuilder.h"
|
||||
#include "llvm/Object/IRObjectFile.h"
|
||||
#include "llvm/Object/ModuleSymbolTable.h"
|
||||
#include "llvm/Object/SymbolicFile.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/StringSaver.h"
|
||||
#include "llvm/Support/VCSRevision.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace irsymtab;
|
||||
|
||||
namespace {
|
||||
|
||||
const char *getExpectedProducerName() {
|
||||
static char DefaultName[] = LLVM_VERSION_STRING
|
||||
#ifdef LLVM_REVISION
|
||||
" " LLVM_REVISION
|
||||
#endif
|
||||
;
|
||||
// Allows for testing of the irsymtab writer and upgrade mechanism. This
|
||||
// environment variable should not be set by users.
|
||||
if (char *OverrideName = getenv("LLVM_OVERRIDE_PRODUCER"))
|
||||
return OverrideName;
|
||||
return DefaultName;
|
||||
}
|
||||
|
||||
const char *kExpectedProducerName = getExpectedProducerName();
|
||||
|
||||
/// Stores the temporary state that is required to build an IR symbol table.
|
||||
struct Builder {
|
||||
SmallVector<char, 0> &Symtab;
|
||||
StringTableBuilder &StrtabBuilder;
|
||||
StringSaver Saver;
|
||||
|
||||
// This ctor initializes a StringSaver using the passed in BumpPtrAllocator.
|
||||
// The StringTableBuilder does not create a copy of any strings added to it,
|
||||
// so this provides somewhere to store any strings that we create.
|
||||
Builder(SmallVector<char, 0> &Symtab, StringTableBuilder &StrtabBuilder,
|
||||
BumpPtrAllocator &Alloc)
|
||||
: Symtab(Symtab), StrtabBuilder(StrtabBuilder), Saver(Alloc) {}
|
||||
|
||||
DenseMap<const Comdat *, int> ComdatMap;
|
||||
Mangler Mang;
|
||||
Triple TT;
|
||||
|
||||
std::vector<storage::Comdat> Comdats;
|
||||
std::vector<storage::Module> Mods;
|
||||
std::vector<storage::Symbol> Syms;
|
||||
std::vector<storage::Uncommon> Uncommons;
|
||||
|
||||
std::string COFFLinkerOpts;
|
||||
raw_string_ostream COFFLinkerOptsOS{COFFLinkerOpts};
|
||||
|
||||
void setStr(storage::Str &S, StringRef Value) {
|
||||
S.Offset = StrtabBuilder.add(Value);
|
||||
S.Size = Value.size();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void writeRange(storage::Range<T> &R, const std::vector<T> &Objs) {
|
||||
R.Offset = Symtab.size();
|
||||
R.Size = Objs.size();
|
||||
Symtab.insert(Symtab.end(), reinterpret_cast<const char *>(Objs.data()),
|
||||
reinterpret_cast<const char *>(Objs.data() + Objs.size()));
|
||||
}
|
||||
|
||||
Expected<int> getComdatIndex(const Comdat *C, const Module *M);
|
||||
|
||||
Error addModule(Module *M);
|
||||
Error addSymbol(const ModuleSymbolTable &Msymtab,
|
||||
const SmallPtrSet<GlobalValue *, 8> &Used,
|
||||
ModuleSymbolTable::Symbol Sym);
|
||||
|
||||
Error build(ArrayRef<Module *> Mods);
|
||||
};
|
||||
|
||||
Error Builder::addModule(Module *M) {
|
||||
if (M->getDataLayoutStr().empty())
|
||||
return make_error<StringError>("input module has no datalayout",
|
||||
inconvertibleErrorCode());
|
||||
|
||||
SmallPtrSet<GlobalValue *, 8> Used;
|
||||
collectUsedGlobalVariables(*M, Used, /*CompilerUsed*/ false);
|
||||
|
||||
ModuleSymbolTable Msymtab;
|
||||
Msymtab.addModule(M);
|
||||
|
||||
storage::Module Mod;
|
||||
Mod.Begin = Syms.size();
|
||||
Mod.End = Syms.size() + Msymtab.symbols().size();
|
||||
Mod.UncBegin = Uncommons.size();
|
||||
Mods.push_back(Mod);
|
||||
|
||||
if (TT.isOSBinFormatCOFF()) {
|
||||
if (auto E = M->materializeMetadata())
|
||||
return E;
|
||||
if (NamedMDNode *LinkerOptions =
|
||||
M->getNamedMetadata("llvm.linker.options")) {
|
||||
for (MDNode *MDOptions : LinkerOptions->operands())
|
||||
for (const MDOperand &MDOption : cast<MDNode>(MDOptions)->operands())
|
||||
COFFLinkerOptsOS << " " << cast<MDString>(MDOption)->getString();
|
||||
}
|
||||
}
|
||||
|
||||
for (ModuleSymbolTable::Symbol Msym : Msymtab.symbols())
|
||||
if (Error Err = addSymbol(Msymtab, Used, Msym))
|
||||
return Err;
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Expected<int> Builder::getComdatIndex(const Comdat *C, const Module *M) {
|
||||
auto P = ComdatMap.insert(std::make_pair(C, Comdats.size()));
|
||||
if (P.second) {
|
||||
std::string Name;
|
||||
if (TT.isOSBinFormatCOFF()) {
|
||||
const GlobalValue *GV = M->getNamedValue(C->getName());
|
||||
if (!GV)
|
||||
return make_error<StringError>("Could not find leader",
|
||||
inconvertibleErrorCode());
|
||||
// Internal leaders do not affect symbol resolution, therefore they do not
|
||||
// appear in the symbol table.
|
||||
if (GV->hasLocalLinkage()) {
|
||||
P.first->second = -1;
|
||||
return -1;
|
||||
}
|
||||
llvm::raw_string_ostream OS(Name);
|
||||
Mang.getNameWithPrefix(OS, GV, false);
|
||||
} else {
|
||||
Name = C->getName();
|
||||
}
|
||||
|
||||
storage::Comdat Comdat;
|
||||
setStr(Comdat.Name, Saver.save(Name));
|
||||
Comdats.push_back(Comdat);
|
||||
}
|
||||
|
||||
return P.first->second;
|
||||
}
|
||||
|
||||
Error Builder::addSymbol(const ModuleSymbolTable &Msymtab,
|
||||
const SmallPtrSet<GlobalValue *, 8> &Used,
|
||||
ModuleSymbolTable::Symbol Msym) {
|
||||
Syms.emplace_back();
|
||||
storage::Symbol &Sym = Syms.back();
|
||||
Sym = {};
|
||||
|
||||
storage::Uncommon *Unc = nullptr;
|
||||
auto Uncommon = [&]() -> storage::Uncommon & {
|
||||
if (Unc)
|
||||
return *Unc;
|
||||
Sym.Flags |= 1 << storage::Symbol::FB_has_uncommon;
|
||||
Uncommons.emplace_back();
|
||||
Unc = &Uncommons.back();
|
||||
*Unc = {};
|
||||
setStr(Unc->COFFWeakExternFallbackName, "");
|
||||
setStr(Unc->SectionName, "");
|
||||
return *Unc;
|
||||
};
|
||||
|
||||
SmallString<64> Name;
|
||||
{
|
||||
raw_svector_ostream OS(Name);
|
||||
Msymtab.printSymbolName(OS, Msym);
|
||||
}
|
||||
setStr(Sym.Name, Saver.save(StringRef(Name)));
|
||||
|
||||
auto Flags = Msymtab.getSymbolFlags(Msym);
|
||||
if (Flags & object::BasicSymbolRef::SF_Undefined)
|
||||
Sym.Flags |= 1 << storage::Symbol::FB_undefined;
|
||||
if (Flags & object::BasicSymbolRef::SF_Weak)
|
||||
Sym.Flags |= 1 << storage::Symbol::FB_weak;
|
||||
if (Flags & object::BasicSymbolRef::SF_Common)
|
||||
Sym.Flags |= 1 << storage::Symbol::FB_common;
|
||||
if (Flags & object::BasicSymbolRef::SF_Indirect)
|
||||
Sym.Flags |= 1 << storage::Symbol::FB_indirect;
|
||||
if (Flags & object::BasicSymbolRef::SF_Global)
|
||||
Sym.Flags |= 1 << storage::Symbol::FB_global;
|
||||
if (Flags & object::BasicSymbolRef::SF_FormatSpecific)
|
||||
Sym.Flags |= 1 << storage::Symbol::FB_format_specific;
|
||||
if (Flags & object::BasicSymbolRef::SF_Executable)
|
||||
Sym.Flags |= 1 << storage::Symbol::FB_executable;
|
||||
|
||||
Sym.ComdatIndex = -1;
|
||||
auto *GV = Msym.dyn_cast<GlobalValue *>();
|
||||
if (!GV) {
|
||||
// Undefined module asm symbols act as GC roots and are implicitly used.
|
||||
if (Flags & object::BasicSymbolRef::SF_Undefined)
|
||||
Sym.Flags |= 1 << storage::Symbol::FB_used;
|
||||
setStr(Sym.IRName, "");
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
setStr(Sym.IRName, GV->getName());
|
||||
|
||||
if (Used.count(GV))
|
||||
Sym.Flags |= 1 << storage::Symbol::FB_used;
|
||||
if (GV->isThreadLocal())
|
||||
Sym.Flags |= 1 << storage::Symbol::FB_tls;
|
||||
if (GV->hasGlobalUnnamedAddr())
|
||||
Sym.Flags |= 1 << storage::Symbol::FB_unnamed_addr;
|
||||
if (canBeOmittedFromSymbolTable(GV))
|
||||
Sym.Flags |= 1 << storage::Symbol::FB_may_omit;
|
||||
Sym.Flags |= unsigned(GV->getVisibility()) << storage::Symbol::FB_visibility;
|
||||
|
||||
if (Flags & object::BasicSymbolRef::SF_Common) {
|
||||
Uncommon().CommonSize = GV->getParent()->getDataLayout().getTypeAllocSize(
|
||||
GV->getType()->getElementType());
|
||||
Uncommon().CommonAlign = GV->getAlignment();
|
||||
}
|
||||
|
||||
const GlobalObject *Base = GV->getBaseObject();
|
||||
if (!Base)
|
||||
return make_error<StringError>("Unable to determine comdat of alias!",
|
||||
inconvertibleErrorCode());
|
||||
if (const Comdat *C = Base->getComdat()) {
|
||||
Expected<int> ComdatIndexOrErr = getComdatIndex(C, GV->getParent());
|
||||
if (!ComdatIndexOrErr)
|
||||
return ComdatIndexOrErr.takeError();
|
||||
Sym.ComdatIndex = *ComdatIndexOrErr;
|
||||
}
|
||||
|
||||
if (TT.isOSBinFormatCOFF()) {
|
||||
emitLinkerFlagsForGlobalCOFF(COFFLinkerOptsOS, GV, TT, Mang);
|
||||
|
||||
if ((Flags & object::BasicSymbolRef::SF_Weak) &&
|
||||
(Flags & object::BasicSymbolRef::SF_Indirect)) {
|
||||
auto *Fallback = dyn_cast<GlobalValue>(
|
||||
cast<GlobalAlias>(GV)->getAliasee()->stripPointerCasts());
|
||||
if (!Fallback)
|
||||
return make_error<StringError>("Invalid weak external",
|
||||
inconvertibleErrorCode());
|
||||
std::string FallbackName;
|
||||
raw_string_ostream OS(FallbackName);
|
||||
Msymtab.printSymbolName(OS, Fallback);
|
||||
OS.flush();
|
||||
setStr(Uncommon().COFFWeakExternFallbackName, Saver.save(FallbackName));
|
||||
}
|
||||
}
|
||||
|
||||
if (!Base->getSection().empty())
|
||||
setStr(Uncommon().SectionName, Saver.save(Base->getSection()));
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error Builder::build(ArrayRef<Module *> IRMods) {
|
||||
storage::Header Hdr;
|
||||
|
||||
assert(!IRMods.empty());
|
||||
Hdr.Version = storage::Header::kCurrentVersion;
|
||||
setStr(Hdr.Producer, kExpectedProducerName);
|
||||
setStr(Hdr.TargetTriple, IRMods[0]->getTargetTriple());
|
||||
setStr(Hdr.SourceFileName, IRMods[0]->getSourceFileName());
|
||||
TT = Triple(IRMods[0]->getTargetTriple());
|
||||
|
||||
for (auto *M : IRMods)
|
||||
if (Error Err = addModule(M))
|
||||
return Err;
|
||||
|
||||
COFFLinkerOptsOS.flush();
|
||||
setStr(Hdr.COFFLinkerOpts, Saver.save(COFFLinkerOpts));
|
||||
|
||||
// We are about to fill in the header's range fields, so reserve space for it
|
||||
// and copy it in afterwards.
|
||||
Symtab.resize(sizeof(storage::Header));
|
||||
writeRange(Hdr.Modules, Mods);
|
||||
writeRange(Hdr.Comdats, Comdats);
|
||||
writeRange(Hdr.Symbols, Syms);
|
||||
writeRange(Hdr.Uncommons, Uncommons);
|
||||
|
||||
*reinterpret_cast<storage::Header *>(Symtab.data()) = Hdr;
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
Error irsymtab::build(ArrayRef<Module *> Mods, SmallVector<char, 0> &Symtab,
|
||||
StringTableBuilder &StrtabBuilder,
|
||||
BumpPtrAllocator &Alloc) {
|
||||
return Builder(Symtab, StrtabBuilder, Alloc).build(Mods);
|
||||
}
|
||||
|
||||
// Upgrade a vector of bitcode modules created by an old version of LLVM by
|
||||
// creating an irsymtab for them in the current format.
|
||||
static Expected<FileContents> upgrade(ArrayRef<BitcodeModule> BMs) {
|
||||
FileContents FC;
|
||||
|
||||
LLVMContext Ctx;
|
||||
std::vector<Module *> Mods;
|
||||
std::vector<std::unique_ptr<Module>> OwnedMods;
|
||||
for (auto BM : BMs) {
|
||||
Expected<std::unique_ptr<Module>> MOrErr =
|
||||
BM.getLazyModule(Ctx, /*ShouldLazyLoadMetadata*/ true,
|
||||
/*IsImporting*/ false);
|
||||
if (!MOrErr)
|
||||
return MOrErr.takeError();
|
||||
|
||||
Mods.push_back(MOrErr->get());
|
||||
OwnedMods.push_back(std::move(*MOrErr));
|
||||
}
|
||||
|
||||
StringTableBuilder StrtabBuilder(StringTableBuilder::RAW);
|
||||
BumpPtrAllocator Alloc;
|
||||
if (Error E = build(Mods, FC.Symtab, StrtabBuilder, Alloc))
|
||||
return std::move(E);
|
||||
|
||||
StrtabBuilder.finalizeInOrder();
|
||||
FC.Strtab.resize(StrtabBuilder.getSize());
|
||||
StrtabBuilder.write((uint8_t *)FC.Strtab.data());
|
||||
|
||||
FC.TheReader = {{FC.Symtab.data(), FC.Symtab.size()},
|
||||
{FC.Strtab.data(), FC.Strtab.size()}};
|
||||
return std::move(FC);
|
||||
}
|
||||
|
||||
Expected<FileContents> irsymtab::readBitcode(const BitcodeFileContents &BFC) {
|
||||
if (BFC.Mods.empty())
|
||||
return make_error<StringError>("Bitcode file does not contain any modules",
|
||||
inconvertibleErrorCode());
|
||||
|
||||
if (BFC.StrtabForSymtab.empty() ||
|
||||
BFC.Symtab.size() < sizeof(storage::Header))
|
||||
return upgrade(BFC.Mods);
|
||||
|
||||
// We cannot use the regular reader to read the version and producer, because
|
||||
// it will expect the header to be in the current format. The only thing we
|
||||
// can rely on is that the version and producer will be present as the first
|
||||
// struct elements.
|
||||
auto *Hdr = reinterpret_cast<const storage::Header *>(BFC.Symtab.data());
|
||||
unsigned Version = Hdr->Version;
|
||||
StringRef Producer = Hdr->Producer.get(BFC.StrtabForSymtab);
|
||||
if (Version != storage::Header::kCurrentVersion ||
|
||||
Producer != kExpectedProducerName)
|
||||
return upgrade(BFC.Mods);
|
||||
|
||||
FileContents FC;
|
||||
FC.TheReader = {{BFC.Symtab.data(), BFC.Symtab.size()},
|
||||
{BFC.StrtabForSymtab.data(), BFC.StrtabForSymtab.size()}};
|
||||
|
||||
// Finally, make sure that the number of modules in the symbol table matches
|
||||
// the number of modules in the bitcode file. If they differ, it may mean that
|
||||
// the bitcode file was created by binary concatenation, so we need to create
|
||||
// a new symbol table from scratch.
|
||||
if (FC.TheReader.getNumModules() != BFC.Mods.size())
|
||||
return upgrade(std::move(BFC.Mods));
|
||||
|
||||
return std::move(FC);
|
||||
}
|
22
external/llvm/lib/Object/LLVMBuild.txt
vendored
22
external/llvm/lib/Object/LLVMBuild.txt
vendored
@ -1,22 +0,0 @@
|
||||
;===- ./lib/Object/LLVMBuild.txt -------------------------------*- Conf -*--===;
|
||||
;
|
||||
; The LLVM Compiler Infrastructure
|
||||
;
|
||||
; This file is distributed under the University of Illinois Open Source
|
||||
; License. See LICENSE.TXT for details.
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
;
|
||||
; This is an LLVMBuild description file for the components in this subdirectory.
|
||||
;
|
||||
; For more information on the LLVMBuild system, please see:
|
||||
;
|
||||
; http://llvm.org/docs/LLVMBuild.html
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[component_0]
|
||||
type = Library
|
||||
name = Object
|
||||
parent = Libraries
|
||||
required_libraries = BitReader Core MC BinaryFormat MCParser Support
|
@ -1 +0,0 @@
|
||||
2e3415618e5f2083aee42bc08fa6ace2148740d1
|
228
external/llvm/lib/Object/MachOUniversal.cpp
vendored
228
external/llvm/lib/Object/MachOUniversal.cpp
vendored
@ -1,228 +0,0 @@
|
||||
//===- MachOUniversal.cpp - Mach-O universal binary -------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the MachOUniversalBinary class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Object/MachOUniversal.h"
|
||||
#include "llvm/Object/Archive.h"
|
||||
#include "llvm/Object/MachO.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/Host.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace object;
|
||||
|
||||
static Error
|
||||
malformedError(Twine Msg) {
|
||||
std::string StringMsg = "truncated or malformed fat file (" + Msg.str() + ")";
|
||||
return make_error<GenericBinaryError>(std::move(StringMsg),
|
||||
object_error::parse_failed);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T getUniversalBinaryStruct(const char *Ptr) {
|
||||
T Res;
|
||||
memcpy(&Res, Ptr, sizeof(T));
|
||||
// Universal binary headers have big-endian byte order.
|
||||
if (sys::IsLittleEndianHost)
|
||||
swapStruct(Res);
|
||||
return Res;
|
||||
}
|
||||
|
||||
MachOUniversalBinary::ObjectForArch::ObjectForArch(
|
||||
const MachOUniversalBinary *Parent, uint32_t Index)
|
||||
: Parent(Parent), Index(Index) {
|
||||
// The iterators use Parent as a nullptr and an Index+1 == NumberOfObjects.
|
||||
if (!Parent || Index >= Parent->getNumberOfObjects()) {
|
||||
clear();
|
||||
} else {
|
||||
// Parse object header.
|
||||
StringRef ParentData = Parent->getData();
|
||||
if (Parent->getMagic() == MachO::FAT_MAGIC) {
|
||||
const char *HeaderPos = ParentData.begin() + sizeof(MachO::fat_header) +
|
||||
Index * sizeof(MachO::fat_arch);
|
||||
Header = getUniversalBinaryStruct<MachO::fat_arch>(HeaderPos);
|
||||
} else { // Parent->getMagic() == MachO::FAT_MAGIC_64
|
||||
const char *HeaderPos = ParentData.begin() + sizeof(MachO::fat_header) +
|
||||
Index * sizeof(MachO::fat_arch_64);
|
||||
Header64 = getUniversalBinaryStruct<MachO::fat_arch_64>(HeaderPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<MachOObjectFile>>
|
||||
MachOUniversalBinary::ObjectForArch::getAsObjectFile() const {
|
||||
if (!Parent)
|
||||
report_fatal_error("MachOUniversalBinary::ObjectForArch::getAsObjectFile() "
|
||||
"called when Parent is a nullptr");
|
||||
|
||||
StringRef ParentData = Parent->getData();
|
||||
StringRef ObjectData;
|
||||
uint32_t cputype;
|
||||
if (Parent->getMagic() == MachO::FAT_MAGIC) {
|
||||
ObjectData = ParentData.substr(Header.offset, Header.size);
|
||||
cputype = Header.cputype;
|
||||
} else { // Parent->getMagic() == MachO::FAT_MAGIC_64
|
||||
ObjectData = ParentData.substr(Header64.offset, Header64.size);
|
||||
cputype = Header64.cputype;
|
||||
}
|
||||
StringRef ObjectName = Parent->getFileName();
|
||||
MemoryBufferRef ObjBuffer(ObjectData, ObjectName);
|
||||
return ObjectFile::createMachOObjectFile(ObjBuffer, cputype, Index);
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<Archive>>
|
||||
MachOUniversalBinary::ObjectForArch::getAsArchive() const {
|
||||
if (!Parent)
|
||||
report_fatal_error("MachOUniversalBinary::ObjectForArch::getAsArchive() "
|
||||
"called when Parent is a nullptr");
|
||||
|
||||
StringRef ParentData = Parent->getData();
|
||||
StringRef ObjectData;
|
||||
if (Parent->getMagic() == MachO::FAT_MAGIC)
|
||||
ObjectData = ParentData.substr(Header.offset, Header.size);
|
||||
else // Parent->getMagic() == MachO::FAT_MAGIC_64
|
||||
ObjectData = ParentData.substr(Header64.offset, Header64.size);
|
||||
StringRef ObjectName = Parent->getFileName();
|
||||
MemoryBufferRef ObjBuffer(ObjectData, ObjectName);
|
||||
return Archive::create(ObjBuffer);
|
||||
}
|
||||
|
||||
void MachOUniversalBinary::anchor() { }
|
||||
|
||||
Expected<std::unique_ptr<MachOUniversalBinary>>
|
||||
MachOUniversalBinary::create(MemoryBufferRef Source) {
|
||||
Error Err = Error::success();
|
||||
std::unique_ptr<MachOUniversalBinary> Ret(
|
||||
new MachOUniversalBinary(Source, Err));
|
||||
if (Err)
|
||||
return std::move(Err);
|
||||
return std::move(Ret);
|
||||
}
|
||||
|
||||
MachOUniversalBinary::MachOUniversalBinary(MemoryBufferRef Source, Error &Err)
|
||||
: Binary(Binary::ID_MachOUniversalBinary, Source), Magic(0),
|
||||
NumberOfObjects(0) {
|
||||
ErrorAsOutParameter ErrAsOutParam(&Err);
|
||||
if (Data.getBufferSize() < sizeof(MachO::fat_header)) {
|
||||
Err = make_error<GenericBinaryError>("File too small to be a Mach-O "
|
||||
"universal file",
|
||||
object_error::invalid_file_type);
|
||||
return;
|
||||
}
|
||||
// Check for magic value and sufficient header size.
|
||||
StringRef Buf = getData();
|
||||
MachO::fat_header H =
|
||||
getUniversalBinaryStruct<MachO::fat_header>(Buf.begin());
|
||||
Magic = H.magic;
|
||||
NumberOfObjects = H.nfat_arch;
|
||||
if (NumberOfObjects == 0) {
|
||||
Err = malformedError("contains zero architecture types");
|
||||
return;
|
||||
}
|
||||
uint32_t MinSize = sizeof(MachO::fat_header);
|
||||
if (Magic == MachO::FAT_MAGIC)
|
||||
MinSize += sizeof(MachO::fat_arch) * NumberOfObjects;
|
||||
else if (Magic == MachO::FAT_MAGIC_64)
|
||||
MinSize += sizeof(MachO::fat_arch_64) * NumberOfObjects;
|
||||
else {
|
||||
Err = malformedError("bad magic number");
|
||||
return;
|
||||
}
|
||||
if (Buf.size() < MinSize) {
|
||||
Err = malformedError("fat_arch" +
|
||||
Twine(Magic == MachO::FAT_MAGIC ? "" : "_64") +
|
||||
" structs would extend past the end of the file");
|
||||
return;
|
||||
}
|
||||
for (uint32_t i = 0; i < NumberOfObjects; i++) {
|
||||
ObjectForArch A(this, i);
|
||||
uint64_t bigSize = A.getOffset();
|
||||
bigSize += A.getSize();
|
||||
if (bigSize > Buf.size()) {
|
||||
Err = malformedError("offset plus size of cputype (" +
|
||||
Twine(A.getCPUType()) + ") cpusubtype (" +
|
||||
Twine(A.getCPUSubType() & ~MachO::CPU_SUBTYPE_MASK) +
|
||||
") extends past the end of the file");
|
||||
return;
|
||||
}
|
||||
#define MAXSECTALIGN 15 /* 2**15 or 0x8000 */
|
||||
if (A.getAlign() > MAXSECTALIGN) {
|
||||
Err = malformedError("align (2^" + Twine(A.getAlign()) + ") too large "
|
||||
"for cputype (" + Twine(A.getCPUType()) + ") cpusubtype (" +
|
||||
Twine(A.getCPUSubType() & ~MachO::CPU_SUBTYPE_MASK) +
|
||||
") (maximum 2^" + Twine(MAXSECTALIGN) + ")");
|
||||
return;
|
||||
}
|
||||
if(A.getOffset() % (1 << A.getAlign()) != 0){
|
||||
Err = malformedError("offset: " + Twine(A.getOffset()) +
|
||||
" for cputype (" + Twine(A.getCPUType()) + ") cpusubtype (" +
|
||||
Twine(A.getCPUSubType() & ~MachO::CPU_SUBTYPE_MASK) +
|
||||
") not aligned on it's alignment (2^" + Twine(A.getAlign()) + ")");
|
||||
return;
|
||||
}
|
||||
if (A.getOffset() < MinSize) {
|
||||
Err = malformedError("cputype (" + Twine(A.getCPUType()) + ") "
|
||||
"cpusubtype (" + Twine(A.getCPUSubType() & ~MachO::CPU_SUBTYPE_MASK) +
|
||||
") offset " + Twine(A.getOffset()) + " overlaps universal headers");
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (uint32_t i = 0; i < NumberOfObjects; i++) {
|
||||
ObjectForArch A(this, i);
|
||||
for (uint32_t j = i + 1; j < NumberOfObjects; j++) {
|
||||
ObjectForArch B(this, j);
|
||||
if (A.getCPUType() == B.getCPUType() &&
|
||||
(A.getCPUSubType() & ~MachO::CPU_SUBTYPE_MASK) ==
|
||||
(B.getCPUSubType() & ~MachO::CPU_SUBTYPE_MASK)) {
|
||||
Err = malformedError("contains two of the same architecture (cputype "
|
||||
"(" + Twine(A.getCPUType()) + ") cpusubtype (" +
|
||||
Twine(A.getCPUSubType() & ~MachO::CPU_SUBTYPE_MASK) + "))");
|
||||
return;
|
||||
}
|
||||
if ((A.getOffset() >= B.getOffset() &&
|
||||
A.getOffset() < B.getOffset() + B.getSize()) ||
|
||||
(A.getOffset() + A.getSize() > B.getOffset() &&
|
||||
A.getOffset() + A.getSize() < B.getOffset() + B.getSize()) ||
|
||||
(A.getOffset() <= B.getOffset() &&
|
||||
A.getOffset() + A.getSize() >= B.getOffset() + B.getSize())) {
|
||||
Err = malformedError("cputype (" + Twine(A.getCPUType()) + ") "
|
||||
"cpusubtype (" + Twine(A.getCPUSubType() & ~MachO::CPU_SUBTYPE_MASK) +
|
||||
") at offset " + Twine(A.getOffset()) + " with a size of " +
|
||||
Twine(A.getSize()) + ", overlaps cputype (" + Twine(B.getCPUType()) +
|
||||
") cpusubtype (" + Twine(B.getCPUSubType() & ~MachO::CPU_SUBTYPE_MASK)
|
||||
+ ") at offset " + Twine(B.getOffset()) + " with a size of "
|
||||
+ Twine(B.getSize()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err = Error::success();
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<MachOObjectFile>>
|
||||
MachOUniversalBinary::getObjectForArch(StringRef ArchName) const {
|
||||
if (Triple(ArchName).getArch() == Triple::ArchType::UnknownArch)
|
||||
return make_error<GenericBinaryError>("Unknown architecture "
|
||||
"named: " +
|
||||
ArchName,
|
||||
object_error::arch_not_found);
|
||||
|
||||
for (auto &Obj : objects())
|
||||
if (Obj.getArchFlagName() == ArchName)
|
||||
return Obj.getAsObjectFile();
|
||||
return make_error<GenericBinaryError>("fat file does not "
|
||||
"contain " +
|
||||
ArchName,
|
||||
object_error::arch_not_found);
|
||||
}
|
280
external/llvm/lib/Object/ModuleSymbolTable.cpp
vendored
280
external/llvm/lib/Object/ModuleSymbolTable.cpp
vendored
@ -1,280 +0,0 @@
|
||||
//===- ModuleSymbolTable.cpp - symbol table for in-memory IR --------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This class represents a symbol table built from in-memory IR. It provides
|
||||
// access to GlobalValues and should only be used if such access is required
|
||||
// (e.g. in the LTO implementation).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Object/ModuleSymbolTable.h"
|
||||
#include "RecordStreamer.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/GlobalAlias.h"
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
#include "llvm/IR/GlobalVariable.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCDirectives.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCObjectFileInfo.h"
|
||||
#include "llvm/MC/MCParser/MCAsmParser.h"
|
||||
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/MC/MCTargetOptions.h"
|
||||
#include "llvm/Object/SymbolicFile.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CodeGen.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/SMLoc.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace object;
|
||||
|
||||
void ModuleSymbolTable::addModule(Module *M) {
|
||||
if (FirstMod)
|
||||
assert(FirstMod->getTargetTriple() == M->getTargetTriple());
|
||||
else
|
||||
FirstMod = M;
|
||||
|
||||
for (GlobalValue &GV : M->global_values())
|
||||
SymTab.push_back(&GV);
|
||||
|
||||
CollectAsmSymbols(*M, [this](StringRef Name, BasicSymbolRef::Flags Flags) {
|
||||
SymTab.push_back(new (AsmSymbols.Allocate()) AsmSymbol(Name, Flags));
|
||||
});
|
||||
}
|
||||
|
||||
// Ensure ELF .symver aliases get the same binding as the defined symbol
|
||||
// they alias with.
|
||||
static void handleSymverAliases(const Module &M, RecordStreamer &Streamer) {
|
||||
if (Streamer.symverAliases().empty())
|
||||
return;
|
||||
|
||||
// The name in the assembler will be mangled, but the name in the IR
|
||||
// might not, so we first compute a mapping from mangled name to GV.
|
||||
Mangler Mang;
|
||||
SmallString<64> MangledName;
|
||||
StringMap<const GlobalValue *> MangledNameMap;
|
||||
auto GetMangledName = [&](const GlobalValue &GV) {
|
||||
if (!GV.hasName())
|
||||
return;
|
||||
|
||||
MangledName.clear();
|
||||
MangledName.reserve(GV.getName().size() + 1);
|
||||
Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
|
||||
MangledNameMap[MangledName] = &GV;
|
||||
};
|
||||
for (const Function &F : M)
|
||||
GetMangledName(F);
|
||||
for (const GlobalVariable &GV : M.globals())
|
||||
GetMangledName(GV);
|
||||
for (const GlobalAlias &GA : M.aliases())
|
||||
GetMangledName(GA);
|
||||
|
||||
// Walk all the recorded .symver aliases, and set up the binding
|
||||
// for each alias.
|
||||
for (auto &Symver : Streamer.symverAliases()) {
|
||||
const MCSymbol *Aliasee = Symver.first;
|
||||
MCSymbolAttr Attr = MCSA_Invalid;
|
||||
|
||||
// First check if the aliasee binding was recorded in the asm.
|
||||
RecordStreamer::State state = Streamer.getSymbolState(Aliasee);
|
||||
switch (state) {
|
||||
case RecordStreamer::Global:
|
||||
case RecordStreamer::DefinedGlobal:
|
||||
Attr = MCSA_Global;
|
||||
break;
|
||||
case RecordStreamer::UndefinedWeak:
|
||||
case RecordStreamer::DefinedWeak:
|
||||
Attr = MCSA_Weak;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// If we don't have a symbol attribute from assembly, then check if
|
||||
// the aliasee was defined in the IR.
|
||||
if (Attr == MCSA_Invalid) {
|
||||
const auto *GV = M.getNamedValue(Aliasee->getName());
|
||||
if (!GV) {
|
||||
auto MI = MangledNameMap.find(Aliasee->getName());
|
||||
if (MI != MangledNameMap.end())
|
||||
GV = MI->second;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
if (GV->hasExternalLinkage())
|
||||
Attr = MCSA_Global;
|
||||
else if (GV->hasLocalLinkage())
|
||||
Attr = MCSA_Local;
|
||||
else if (GV->isWeakForLinker())
|
||||
Attr = MCSA_Weak;
|
||||
}
|
||||
if (Attr == MCSA_Invalid)
|
||||
continue;
|
||||
|
||||
// Set the detected binding on each alias with this aliasee.
|
||||
for (auto &Alias : Symver.second)
|
||||
Streamer.EmitSymbolAttribute(Alias, Attr);
|
||||
}
|
||||
}
|
||||
|
||||
void ModuleSymbolTable::CollectAsmSymbols(
|
||||
const Module &M,
|
||||
function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) {
|
||||
StringRef InlineAsm = M.getModuleInlineAsm();
|
||||
if (InlineAsm.empty())
|
||||
return;
|
||||
|
||||
std::string Err;
|
||||
const Triple TT(M.getTargetTriple());
|
||||
const Target *T = TargetRegistry::lookupTarget(TT.str(), Err);
|
||||
assert(T && T->hasMCAsmParser());
|
||||
|
||||
std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str()));
|
||||
if (!MRI)
|
||||
return;
|
||||
|
||||
std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str()));
|
||||
if (!MAI)
|
||||
return;
|
||||
|
||||
std::unique_ptr<MCSubtargetInfo> STI(
|
||||
T->createMCSubtargetInfo(TT.str(), "", ""));
|
||||
if (!STI)
|
||||
return;
|
||||
|
||||
std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo());
|
||||
if (!MCII)
|
||||
return;
|
||||
|
||||
MCObjectFileInfo MOFI;
|
||||
MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
|
||||
MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, MCCtx);
|
||||
RecordStreamer Streamer(MCCtx);
|
||||
T->createNullTargetStreamer(Streamer);
|
||||
|
||||
std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm));
|
||||
SourceMgr SrcMgr;
|
||||
SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
|
||||
std::unique_ptr<MCAsmParser> Parser(
|
||||
createMCAsmParser(SrcMgr, MCCtx, Streamer, *MAI));
|
||||
|
||||
MCTargetOptions MCOptions;
|
||||
std::unique_ptr<MCTargetAsmParser> TAP(
|
||||
T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));
|
||||
if (!TAP)
|
||||
return;
|
||||
|
||||
Parser->setTargetParser(*TAP);
|
||||
if (Parser->Run(false))
|
||||
return;
|
||||
|
||||
handleSymverAliases(M, Streamer);
|
||||
|
||||
for (auto &KV : Streamer) {
|
||||
StringRef Key = KV.first();
|
||||
RecordStreamer::State Value = KV.second;
|
||||
// FIXME: For now we just assume that all asm symbols are executable.
|
||||
uint32_t Res = BasicSymbolRef::SF_Executable;
|
||||
switch (Value) {
|
||||
case RecordStreamer::NeverSeen:
|
||||
llvm_unreachable("NeverSeen should have been replaced earlier");
|
||||
case RecordStreamer::DefinedGlobal:
|
||||
Res |= BasicSymbolRef::SF_Global;
|
||||
break;
|
||||
case RecordStreamer::Defined:
|
||||
break;
|
||||
case RecordStreamer::Global:
|
||||
case RecordStreamer::Used:
|
||||
Res |= BasicSymbolRef::SF_Undefined;
|
||||
Res |= BasicSymbolRef::SF_Global;
|
||||
break;
|
||||
case RecordStreamer::DefinedWeak:
|
||||
Res |= BasicSymbolRef::SF_Weak;
|
||||
Res |= BasicSymbolRef::SF_Global;
|
||||
break;
|
||||
case RecordStreamer::UndefinedWeak:
|
||||
Res |= BasicSymbolRef::SF_Weak;
|
||||
Res |= BasicSymbolRef::SF_Undefined;
|
||||
}
|
||||
AsmSymbol(Key, BasicSymbolRef::Flags(Res));
|
||||
}
|
||||
}
|
||||
|
||||
void ModuleSymbolTable::printSymbolName(raw_ostream &OS, Symbol S) const {
|
||||
if (S.is<AsmSymbol *>()) {
|
||||
OS << S.get<AsmSymbol *>()->first;
|
||||
return;
|
||||
}
|
||||
|
||||
auto *GV = S.get<GlobalValue *>();
|
||||
if (GV->hasDLLImportStorageClass())
|
||||
OS << "__imp_";
|
||||
|
||||
Mang.getNameWithPrefix(OS, GV, false);
|
||||
}
|
||||
|
||||
uint32_t ModuleSymbolTable::getSymbolFlags(Symbol S) const {
|
||||
if (S.is<AsmSymbol *>())
|
||||
return S.get<AsmSymbol *>()->second;
|
||||
|
||||
auto *GV = S.get<GlobalValue *>();
|
||||
|
||||
uint32_t Res = BasicSymbolRef::SF_None;
|
||||
if (GV->isDeclarationForLinker())
|
||||
Res |= BasicSymbolRef::SF_Undefined;
|
||||
else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage())
|
||||
Res |= BasicSymbolRef::SF_Hidden;
|
||||
if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) {
|
||||
if (GVar->isConstant())
|
||||
Res |= BasicSymbolRef::SF_Const;
|
||||
}
|
||||
if (dyn_cast_or_null<Function>(GV->getBaseObject()))
|
||||
Res |= BasicSymbolRef::SF_Executable;
|
||||
if (isa<GlobalAlias>(GV))
|
||||
Res |= BasicSymbolRef::SF_Indirect;
|
||||
if (GV->hasPrivateLinkage())
|
||||
Res |= BasicSymbolRef::SF_FormatSpecific;
|
||||
if (!GV->hasLocalLinkage())
|
||||
Res |= BasicSymbolRef::SF_Global;
|
||||
if (GV->hasCommonLinkage())
|
||||
Res |= BasicSymbolRef::SF_Common;
|
||||
if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() ||
|
||||
GV->hasExternalWeakLinkage())
|
||||
Res |= BasicSymbolRef::SF_Weak;
|
||||
|
||||
if (GV->getName().startswith("llvm."))
|
||||
Res |= BasicSymbolRef::SF_FormatSpecific;
|
||||
else if (auto *Var = dyn_cast<GlobalVariable>(GV)) {
|
||||
if (Var->getSection() == "llvm.metadata")
|
||||
Res |= BasicSymbolRef::SF_FormatSpecific;
|
||||
}
|
||||
|
||||
return Res;
|
||||
}
|
240
external/llvm/lib/Object/Object.cpp
vendored
240
external/llvm/lib/Object/Object.cpp
vendored
@ -1,240 +0,0 @@
|
||||
//===- Object.cpp - C bindings to the object file library--------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the C bindings to the file-format-independent object
|
||||
// library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm-c/Object.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace object;
|
||||
|
||||
inline OwningBinary<ObjectFile> *unwrap(LLVMObjectFileRef OF) {
|
||||
return reinterpret_cast<OwningBinary<ObjectFile> *>(OF);
|
||||
}
|
||||
|
||||
inline LLVMObjectFileRef wrap(const OwningBinary<ObjectFile> *OF) {
|
||||
return reinterpret_cast<LLVMObjectFileRef>(
|
||||
const_cast<OwningBinary<ObjectFile> *>(OF));
|
||||
}
|
||||
|
||||
inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
|
||||
return reinterpret_cast<section_iterator*>(SI);
|
||||
}
|
||||
|
||||
inline LLVMSectionIteratorRef
|
||||
wrap(const section_iterator *SI) {
|
||||
return reinterpret_cast<LLVMSectionIteratorRef>
|
||||
(const_cast<section_iterator*>(SI));
|
||||
}
|
||||
|
||||
inline symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) {
|
||||
return reinterpret_cast<symbol_iterator*>(SI);
|
||||
}
|
||||
|
||||
inline LLVMSymbolIteratorRef
|
||||
wrap(const symbol_iterator *SI) {
|
||||
return reinterpret_cast<LLVMSymbolIteratorRef>
|
||||
(const_cast<symbol_iterator*>(SI));
|
||||
}
|
||||
|
||||
inline relocation_iterator *unwrap(LLVMRelocationIteratorRef SI) {
|
||||
return reinterpret_cast<relocation_iterator*>(SI);
|
||||
}
|
||||
|
||||
inline LLVMRelocationIteratorRef
|
||||
wrap(const relocation_iterator *SI) {
|
||||
return reinterpret_cast<LLVMRelocationIteratorRef>
|
||||
(const_cast<relocation_iterator*>(SI));
|
||||
}
|
||||
|
||||
// ObjectFile creation
|
||||
LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {
|
||||
std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf));
|
||||
Expected<std::unique_ptr<ObjectFile>> ObjOrErr(
|
||||
ObjectFile::createObjectFile(Buf->getMemBufferRef()));
|
||||
std::unique_ptr<ObjectFile> Obj;
|
||||
if (!ObjOrErr) {
|
||||
// TODO: Actually report errors helpfully.
|
||||
consumeError(ObjOrErr.takeError());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto *Ret = new OwningBinary<ObjectFile>(std::move(ObjOrErr.get()), std::move(Buf));
|
||||
return wrap(Ret);
|
||||
}
|
||||
|
||||
void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) {
|
||||
delete unwrap(ObjectFile);
|
||||
}
|
||||
|
||||
// ObjectFile Section iterators
|
||||
LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef OF) {
|
||||
OwningBinary<ObjectFile> *OB = unwrap(OF);
|
||||
section_iterator SI = OB->getBinary()->section_begin();
|
||||
return wrap(new section_iterator(SI));
|
||||
}
|
||||
|
||||
void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) {
|
||||
delete unwrap(SI);
|
||||
}
|
||||
|
||||
LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF,
|
||||
LLVMSectionIteratorRef SI) {
|
||||
OwningBinary<ObjectFile> *OB = unwrap(OF);
|
||||
return (*unwrap(SI) == OB->getBinary()->section_end()) ? 1 : 0;
|
||||
}
|
||||
|
||||
void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) {
|
||||
++(*unwrap(SI));
|
||||
}
|
||||
|
||||
void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,
|
||||
LLVMSymbolIteratorRef Sym) {
|
||||
Expected<section_iterator> SecOrErr = (*unwrap(Sym))->getSection();
|
||||
if (!SecOrErr) {
|
||||
std::string Buf;
|
||||
raw_string_ostream OS(Buf);
|
||||
logAllUnhandledErrors(SecOrErr.takeError(), OS, "");
|
||||
OS.flush();
|
||||
report_fatal_error(Buf);
|
||||
}
|
||||
*unwrap(Sect) = *SecOrErr;
|
||||
}
|
||||
|
||||
// ObjectFile Symbol iterators
|
||||
LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef OF) {
|
||||
OwningBinary<ObjectFile> *OB = unwrap(OF);
|
||||
symbol_iterator SI = OB->getBinary()->symbol_begin();
|
||||
return wrap(new symbol_iterator(SI));
|
||||
}
|
||||
|
||||
void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) {
|
||||
delete unwrap(SI);
|
||||
}
|
||||
|
||||
LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF,
|
||||
LLVMSymbolIteratorRef SI) {
|
||||
OwningBinary<ObjectFile> *OB = unwrap(OF);
|
||||
return (*unwrap(SI) == OB->getBinary()->symbol_end()) ? 1 : 0;
|
||||
}
|
||||
|
||||
void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) {
|
||||
++(*unwrap(SI));
|
||||
}
|
||||
|
||||
// SectionRef accessors
|
||||
const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) {
|
||||
StringRef ret;
|
||||
if (std::error_code ec = (*unwrap(SI))->getName(ret))
|
||||
report_fatal_error(ec.message());
|
||||
return ret.data();
|
||||
}
|
||||
|
||||
uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) {
|
||||
return (*unwrap(SI))->getSize();
|
||||
}
|
||||
|
||||
const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) {
|
||||
StringRef ret;
|
||||
if (std::error_code ec = (*unwrap(SI))->getContents(ret))
|
||||
report_fatal_error(ec.message());
|
||||
return ret.data();
|
||||
}
|
||||
|
||||
uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) {
|
||||
return (*unwrap(SI))->getAddress();
|
||||
}
|
||||
|
||||
LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI,
|
||||
LLVMSymbolIteratorRef Sym) {
|
||||
return (*unwrap(SI))->containsSymbol(**unwrap(Sym));
|
||||
}
|
||||
|
||||
// Section Relocation iterators
|
||||
LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) {
|
||||
relocation_iterator SI = (*unwrap(Section))->relocation_begin();
|
||||
return wrap(new relocation_iterator(SI));
|
||||
}
|
||||
|
||||
void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) {
|
||||
delete unwrap(SI);
|
||||
}
|
||||
|
||||
LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section,
|
||||
LLVMRelocationIteratorRef SI) {
|
||||
return (*unwrap(SI) == (*unwrap(Section))->relocation_end()) ? 1 : 0;
|
||||
}
|
||||
|
||||
void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) {
|
||||
++(*unwrap(SI));
|
||||
}
|
||||
|
||||
|
||||
// SymbolRef accessors
|
||||
const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) {
|
||||
Expected<StringRef> Ret = (*unwrap(SI))->getName();
|
||||
if (!Ret) {
|
||||
std::string Buf;
|
||||
raw_string_ostream OS(Buf);
|
||||
logAllUnhandledErrors(Ret.takeError(), OS, "");
|
||||
OS.flush();
|
||||
report_fatal_error(Buf);
|
||||
}
|
||||
return Ret->data();
|
||||
}
|
||||
|
||||
uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) {
|
||||
Expected<uint64_t> Ret = (*unwrap(SI))->getAddress();
|
||||
if (!Ret) {
|
||||
std::string Buf;
|
||||
raw_string_ostream OS(Buf);
|
||||
logAllUnhandledErrors(Ret.takeError(), OS, "");
|
||||
OS.flush();
|
||||
report_fatal_error(Buf);
|
||||
}
|
||||
return *Ret;
|
||||
}
|
||||
|
||||
uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) {
|
||||
return (*unwrap(SI))->getCommonSize();
|
||||
}
|
||||
|
||||
// RelocationRef accessors
|
||||
uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) {
|
||||
return (*unwrap(RI))->getOffset();
|
||||
}
|
||||
|
||||
LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) {
|
||||
symbol_iterator ret = (*unwrap(RI))->getSymbol();
|
||||
return wrap(new symbol_iterator(ret));
|
||||
}
|
||||
|
||||
uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) {
|
||||
return (*unwrap(RI))->getType();
|
||||
}
|
||||
|
||||
// NOTE: Caller takes ownership of returned string.
|
||||
const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) {
|
||||
SmallVector<char, 0> ret;
|
||||
(*unwrap(RI))->getTypeName(ret);
|
||||
char *str = static_cast<char*>(malloc(ret.size()));
|
||||
std::copy(ret.begin(), ret.end(), str);
|
||||
return str;
|
||||
}
|
||||
|
||||
// NOTE: Caller takes ownership of returned string.
|
||||
const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) {
|
||||
return strdup("");
|
||||
}
|
||||
|
166
external/llvm/lib/Object/ObjectFile.cpp
vendored
166
external/llvm/lib/Object/ObjectFile.cpp
vendored
@ -1,166 +0,0 @@
|
||||
//===- ObjectFile.cpp - File format independent object file ---------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines a file format independent ObjectFile class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/BinaryFormat/Magic.h"
|
||||
#include "llvm/Object/Binary.h"
|
||||
#include "llvm/Object/COFF.h"
|
||||
#include "llvm/Object/Error.h"
|
||||
#include "llvm/Object/MachO.h"
|
||||
#include "llvm/Object/Wasm.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/ErrorOr.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <system_error>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace object;
|
||||
|
||||
void ObjectFile::anchor() {}
|
||||
|
||||
ObjectFile::ObjectFile(unsigned int Type, MemoryBufferRef Source)
|
||||
: SymbolicFile(Type, Source) {}
|
||||
|
||||
bool SectionRef::containsSymbol(SymbolRef S) const {
|
||||
Expected<section_iterator> SymSec = S.getSection();
|
||||
if (!SymSec) {
|
||||
// TODO: Actually report errors helpfully.
|
||||
consumeError(SymSec.takeError());
|
||||
return false;
|
||||
}
|
||||
return *this == **SymSec;
|
||||
}
|
||||
|
||||
uint64_t ObjectFile::getSymbolValue(DataRefImpl Ref) const {
|
||||
uint32_t Flags = getSymbolFlags(Ref);
|
||||
if (Flags & SymbolRef::SF_Undefined)
|
||||
return 0;
|
||||
if (Flags & SymbolRef::SF_Common)
|
||||
return getCommonSymbolSize(Ref);
|
||||
return getSymbolValueImpl(Ref);
|
||||
}
|
||||
|
||||
std::error_code ObjectFile::printSymbolName(raw_ostream &OS,
|
||||
DataRefImpl Symb) const {
|
||||
Expected<StringRef> Name = getSymbolName(Symb);
|
||||
if (!Name)
|
||||
return errorToErrorCode(Name.takeError());
|
||||
OS << *Name;
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
uint32_t ObjectFile::getSymbolAlignment(DataRefImpl DRI) const { return 0; }
|
||||
|
||||
bool ObjectFile::isSectionBitcode(DataRefImpl Sec) const {
|
||||
StringRef SectName;
|
||||
if (!getSectionName(Sec, SectName))
|
||||
return SectName == ".llvmbc";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ObjectFile::isSectionStripped(DataRefImpl Sec) const { return false; }
|
||||
|
||||
section_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const {
|
||||
return section_iterator(SectionRef(Sec, this));
|
||||
}
|
||||
|
||||
Triple ObjectFile::makeTriple() const {
|
||||
Triple TheTriple;
|
||||
auto Arch = getArch();
|
||||
TheTriple.setArch(Triple::ArchType(Arch));
|
||||
|
||||
// For ARM targets, try to use the build attributes to build determine
|
||||
// the build target. Target features are also added, but later during
|
||||
// disassembly.
|
||||
if (Arch == Triple::arm || Arch == Triple::armeb)
|
||||
setARMSubArch(TheTriple);
|
||||
|
||||
// TheTriple defaults to ELF, and COFF doesn't have an environment:
|
||||
// the best we can do here is indicate that it is mach-o.
|
||||
if (isMachO())
|
||||
TheTriple.setObjectFormat(Triple::MachO);
|
||||
|
||||
if (isCOFF()) {
|
||||
const auto COFFObj = dyn_cast<COFFObjectFile>(this);
|
||||
if (COFFObj->getArch() == Triple::thumb)
|
||||
TheTriple.setTriple("thumbv7-windows");
|
||||
}
|
||||
|
||||
return TheTriple;
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<ObjectFile>>
|
||||
ObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type) {
|
||||
StringRef Data = Object.getBuffer();
|
||||
if (Type == file_magic::unknown)
|
||||
Type = identify_magic(Data);
|
||||
|
||||
switch (Type) {
|
||||
case file_magic::unknown:
|
||||
case file_magic::bitcode:
|
||||
case file_magic::coff_cl_gl_object:
|
||||
case file_magic::archive:
|
||||
case file_magic::macho_universal_binary:
|
||||
case file_magic::windows_resource:
|
||||
return errorCodeToError(object_error::invalid_file_type);
|
||||
case file_magic::elf:
|
||||
case file_magic::elf_relocatable:
|
||||
case file_magic::elf_executable:
|
||||
case file_magic::elf_shared_object:
|
||||
case file_magic::elf_core:
|
||||
return createELFObjectFile(Object);
|
||||
case file_magic::macho_object:
|
||||
case file_magic::macho_executable:
|
||||
case file_magic::macho_fixed_virtual_memory_shared_lib:
|
||||
case file_magic::macho_core:
|
||||
case file_magic::macho_preload_executable:
|
||||
case file_magic::macho_dynamically_linked_shared_lib:
|
||||
case file_magic::macho_dynamic_linker:
|
||||
case file_magic::macho_bundle:
|
||||
case file_magic::macho_dynamically_linked_shared_lib_stub:
|
||||
case file_magic::macho_dsym_companion:
|
||||
case file_magic::macho_kext_bundle:
|
||||
return createMachOObjectFile(Object);
|
||||
case file_magic::coff_object:
|
||||
case file_magic::coff_import_library:
|
||||
case file_magic::pecoff_executable:
|
||||
return createCOFFObjectFile(Object);
|
||||
case file_magic::wasm_object:
|
||||
return createWasmObjectFile(Object);
|
||||
}
|
||||
llvm_unreachable("Unexpected Object File Type");
|
||||
}
|
||||
|
||||
Expected<OwningBinary<ObjectFile>>
|
||||
ObjectFile::createObjectFile(StringRef ObjectPath) {
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
|
||||
MemoryBuffer::getFile(ObjectPath);
|
||||
if (std::error_code EC = FileOrErr.getError())
|
||||
return errorCodeToError(EC);
|
||||
std::unique_ptr<MemoryBuffer> Buffer = std::move(FileOrErr.get());
|
||||
|
||||
Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
|
||||
createObjectFile(Buffer->getMemBufferRef());
|
||||
if (Error Err = ObjOrErr.takeError())
|
||||
return std::move(Err);
|
||||
std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get());
|
||||
|
||||
return OwningBinary<ObjectFile>(std::move(Obj), std::move(Buffer));
|
||||
}
|
118
external/llvm/lib/Object/RecordStreamer.cpp
vendored
118
external/llvm/lib/Object/RecordStreamer.cpp
vendored
@ -1,118 +0,0 @@
|
||||
//===-- RecordStreamer.cpp - Record asm defined and used symbols ----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "RecordStreamer.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
void RecordStreamer::markDefined(const MCSymbol &Symbol) {
|
||||
State &S = Symbols[Symbol.getName()];
|
||||
switch (S) {
|
||||
case DefinedGlobal:
|
||||
case Global:
|
||||
S = DefinedGlobal;
|
||||
break;
|
||||
case NeverSeen:
|
||||
case Defined:
|
||||
case Used:
|
||||
S = Defined;
|
||||
break;
|
||||
case DefinedWeak:
|
||||
break;
|
||||
case UndefinedWeak:
|
||||
S = DefinedWeak;
|
||||
}
|
||||
}
|
||||
|
||||
void RecordStreamer::markGlobal(const MCSymbol &Symbol,
|
||||
MCSymbolAttr Attribute) {
|
||||
State &S = Symbols[Symbol.getName()];
|
||||
switch (S) {
|
||||
case DefinedGlobal:
|
||||
case Defined:
|
||||
S = (Attribute == MCSA_Weak) ? DefinedWeak : DefinedGlobal;
|
||||
break;
|
||||
|
||||
case NeverSeen:
|
||||
case Global:
|
||||
case Used:
|
||||
S = (Attribute == MCSA_Weak) ? UndefinedWeak : Global;
|
||||
break;
|
||||
case UndefinedWeak:
|
||||
case DefinedWeak:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RecordStreamer::markUsed(const MCSymbol &Symbol) {
|
||||
State &S = Symbols[Symbol.getName()];
|
||||
switch (S) {
|
||||
case DefinedGlobal:
|
||||
case Defined:
|
||||
case Global:
|
||||
case DefinedWeak:
|
||||
case UndefinedWeak:
|
||||
break;
|
||||
|
||||
case NeverSeen:
|
||||
case Used:
|
||||
S = Used;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RecordStreamer::visitUsedSymbol(const MCSymbol &Sym) { markUsed(Sym); }
|
||||
|
||||
RecordStreamer::RecordStreamer(MCContext &Context) : MCStreamer(Context) {}
|
||||
|
||||
RecordStreamer::const_iterator RecordStreamer::begin() {
|
||||
return Symbols.begin();
|
||||
}
|
||||
|
||||
RecordStreamer::const_iterator RecordStreamer::end() { return Symbols.end(); }
|
||||
|
||||
void RecordStreamer::EmitInstruction(const MCInst &Inst,
|
||||
const MCSubtargetInfo &STI, bool) {
|
||||
MCStreamer::EmitInstruction(Inst, STI);
|
||||
}
|
||||
|
||||
void RecordStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
|
||||
MCStreamer::EmitLabel(Symbol);
|
||||
markDefined(*Symbol);
|
||||
}
|
||||
|
||||
void RecordStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
|
||||
markDefined(*Symbol);
|
||||
MCStreamer::EmitAssignment(Symbol, Value);
|
||||
}
|
||||
|
||||
bool RecordStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
|
||||
MCSymbolAttr Attribute) {
|
||||
if (Attribute == MCSA_Global || Attribute == MCSA_Weak)
|
||||
markGlobal(*Symbol, Attribute);
|
||||
if (Attribute == MCSA_LazyReference)
|
||||
markUsed(*Symbol);
|
||||
return true;
|
||||
}
|
||||
|
||||
void RecordStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
|
||||
uint64_t Size, unsigned ByteAlignment) {
|
||||
markDefined(*Symbol);
|
||||
}
|
||||
|
||||
void RecordStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
||||
unsigned ByteAlignment) {
|
||||
markDefined(*Symbol);
|
||||
}
|
||||
|
||||
void RecordStreamer::emitELFSymverDirective(MCSymbol *Alias,
|
||||
const MCSymbol *Aliasee) {
|
||||
SymverAliasMap[Aliasee].push_back(Alias);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user