forked from OSchip/llvm-project
[lld-macho][reland] Add support for emitting dylibs with a single symbol
This got reverted due to UBSAN errors in a diff lower in the stack, which is being fixed in https://reviews.llvm.org/D79050. This diff is otherwise identical to the original https://reviews.llvm.org/D76908 (which was committed in9598778bd1
and reverted inb52bc2653b
). Differential Revision: https://reviews.llvm.org/D79051
This commit is contained in:
parent
4f0cccdd7a
commit
62b8f32f76
|
@ -10,6 +10,7 @@
|
|||
#define LLD_MACHO_CONFIG_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/BinaryFormat/MachO.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
@ -19,9 +20,10 @@ namespace macho {
|
|||
class Symbol;
|
||||
|
||||
struct Configuration {
|
||||
llvm::StringRef outputFile;
|
||||
Symbol *entry;
|
||||
|
||||
llvm::MachO::HeaderFileType outputType;
|
||||
llvm::StringRef installName;
|
||||
llvm::StringRef outputFile;
|
||||
std::vector<llvm::StringRef> searchPaths;
|
||||
};
|
||||
|
||||
|
|
|
@ -128,7 +128,10 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
|
|||
|
||||
config->entry = symtab->addUndefined(args.getLastArgValue(OPT_e, "_main"));
|
||||
config->outputFile = args.getLastArgValue(OPT_o, "a.out");
|
||||
config->installName =
|
||||
args.getLastArgValue(OPT_install_name, config->outputFile);
|
||||
config->searchPaths = getSearchPaths(args);
|
||||
config->outputType = args.hasArg(OPT_dylib) ? MH_DYLIB : MH_EXECUTE;
|
||||
|
||||
if (args.hasArg(OPT_v)) {
|
||||
message(getLLDVersion());
|
||||
|
@ -151,7 +154,7 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
|
|||
}
|
||||
}
|
||||
|
||||
if (!isa<Defined>(config->entry)) {
|
||||
if (config->outputType == MH_EXECUTE && !isa<Defined>(config->entry)) {
|
||||
error("undefined symbol: " + config->entry->getName());
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -9,8 +9,14 @@ def Z: Flag<["-"], "Z">,
|
|||
def arch: Separate<["-"], "arch">, MetaVarName<"<arch-name>">,
|
||||
HelpText<"Architecture to link">;
|
||||
|
||||
def dylib: Flag<["-"], "dylib">, HelpText<"Emit a shared library">;
|
||||
|
||||
def e: Separate<["-"], "e">, HelpText<"Name of entry point symbol">;
|
||||
|
||||
def install_name: Separate<["-"], "install_name">,
|
||||
MetaVarName<"<install-name>">,
|
||||
HelpText<"Set the install path of the dynamic library.">;
|
||||
|
||||
def l: Joined<["-"], "l">, MetaVarName<"<libname>">,
|
||||
HelpText<"Base name of library searched for in -L directories">;
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "SyntheticSections.h"
|
||||
#include "Config.h"
|
||||
#include "InputFiles.h"
|
||||
#include "OutputSegment.h"
|
||||
#include "SymbolTable.h"
|
||||
|
@ -45,7 +46,7 @@ void MachHeaderSection::writeTo(uint8_t *buf) {
|
|||
hdr->magic = MH_MAGIC_64;
|
||||
hdr->cputype = CPU_TYPE_X86_64;
|
||||
hdr->cpusubtype = CPU_SUBTYPE_X86_64_ALL | CPU_SUBTYPE_LIB64;
|
||||
hdr->filetype = MH_EXECUTE;
|
||||
hdr->filetype = config->outputType;
|
||||
hdr->ncmds = loadCommands.size();
|
||||
hdr->sizeofcmds = sizeOfCmds;
|
||||
hdr->flags = MH_NOUNDEFS | MH_DYLDLINK | MH_TWOLEVEL;
|
||||
|
@ -129,6 +130,45 @@ void BindingSection::writeTo(uint8_t *buf) {
|
|||
memcpy(buf, contents.data(), contents.size());
|
||||
}
|
||||
|
||||
ExportSection::ExportSection() {
|
||||
segname = segment_names::linkEdit;
|
||||
name = section_names::export_;
|
||||
}
|
||||
|
||||
void ExportSection::finalizeContents() {
|
||||
raw_svector_ostream os{contents};
|
||||
std::vector<const Defined *> exported;
|
||||
// TODO: We should check symbol visibility.
|
||||
for (const Symbol *sym : symtab->getSymbols())
|
||||
if (auto *defined = dyn_cast<Defined>(sym))
|
||||
exported.push_back(defined);
|
||||
|
||||
if (exported.empty())
|
||||
return;
|
||||
|
||||
if (exported.size() > 1) {
|
||||
error("TODO: Unable to export more than 1 symbol");
|
||||
return;
|
||||
}
|
||||
|
||||
const Defined *sym = exported.front();
|
||||
os << (char)0; // Indicates non-leaf node
|
||||
os << (char)1; // # of children
|
||||
os << sym->getName() << '\0';
|
||||
encodeULEB128(sym->getName().size() + 4, os); // Leaf offset
|
||||
|
||||
// Leaf node
|
||||
uint64_t addr = sym->getVA() + ImageBase;
|
||||
os << (char)(1 + getULEB128Size(addr));
|
||||
os << (char)0; // Flags
|
||||
encodeULEB128(addr, os);
|
||||
os << (char)0; // Terminator
|
||||
}
|
||||
|
||||
void ExportSection::writeTo(uint8_t *buf) {
|
||||
memcpy(buf, contents.data(), contents.size());
|
||||
}
|
||||
|
||||
SymtabSection::SymtabSection(StringTableSection &stringTableSection)
|
||||
: stringTableSection(stringTableSection) {
|
||||
segname = segment_names::linkEdit;
|
||||
|
@ -143,24 +183,24 @@ size_t SymtabSection::getSize() const {
|
|||
}
|
||||
|
||||
void SymtabSection::finalizeContents() {
|
||||
// TODO: We should filter out some symbols.
|
||||
// TODO support other symbol types
|
||||
for (Symbol *sym : symtab->getSymbols())
|
||||
if (isa<Defined>(sym))
|
||||
symbols.push_back({sym, stringTableSection.addString(sym->getName())});
|
||||
}
|
||||
|
||||
void SymtabSection::writeTo(uint8_t *buf) {
|
||||
auto *nList = reinterpret_cast<nlist_64 *>(buf);
|
||||
for (const SymtabEntry &entry : symbols) {
|
||||
nList->n_strx = entry.strx;
|
||||
// TODO support other symbol types
|
||||
// TODO populate n_desc
|
||||
if (auto defined = dyn_cast<Defined>(entry.sym)) {
|
||||
nList->n_strx = entry.strx;
|
||||
nList->n_type = N_EXT | N_SECT;
|
||||
nList->n_sect = defined->isec->sectionIndex;
|
||||
// For the N_SECT symbol type, n_value is the address of the symbol
|
||||
nList->n_value = defined->value + defined->isec->addr;
|
||||
}
|
||||
|
||||
++nList;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace section_names {
|
|||
constexpr const char *pageZero = "__pagezero";
|
||||
constexpr const char *header = "__mach_header";
|
||||
constexpr const char *binding = "__binding";
|
||||
constexpr const char *export_ = "__export";
|
||||
constexpr const char *symbolTable = "__symbol_table";
|
||||
constexpr const char *stringTable = "__string_table";
|
||||
|
||||
|
@ -95,6 +96,21 @@ public:
|
|||
SmallVector<char, 128> contents;
|
||||
};
|
||||
|
||||
// Stores a trie that describes the set of exported symbols.
|
||||
class ExportSection : public InputSection {
|
||||
public:
|
||||
ExportSection();
|
||||
void finalizeContents();
|
||||
size_t getSize() const override { return contents.size(); }
|
||||
// Like other sections in __LINKEDIT, the export section is special: its
|
||||
// offsets are recorded in the LC_DYLD_INFO_ONLY load command, instead of in
|
||||
// section headers.
|
||||
bool isHidden() const override { return true; }
|
||||
void writeTo(uint8_t *buf) override;
|
||||
|
||||
SmallVector<char, 128> contents;
|
||||
};
|
||||
|
||||
// Stores the strings referenced by the symbol table.
|
||||
class StringTableSection : public InputSection {
|
||||
public:
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "lld/Common/ErrorHandler.h"
|
||||
#include "lld/Common/Memory.h"
|
||||
#include "llvm/BinaryFormat/MachO.h"
|
||||
#include "llvm/Support/LEB128.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
@ -52,14 +53,16 @@ public:
|
|||
uint64_t fileOff = 0;
|
||||
MachHeaderSection *headerSection = nullptr;
|
||||
BindingSection *bindingSection = nullptr;
|
||||
SymtabSection *symtabSection = nullptr;
|
||||
ExportSection *exportSection = nullptr;
|
||||
StringTableSection *stringTableSection = nullptr;
|
||||
SymtabSection *symtabSection = nullptr;
|
||||
};
|
||||
|
||||
// LC_DYLD_INFO_ONLY stores the offsets of symbol import/export information.
|
||||
class LCDyldInfo : public LoadCommand {
|
||||
public:
|
||||
LCDyldInfo(BindingSection *bindingSection) : bindingSection(bindingSection) {}
|
||||
LCDyldInfo(BindingSection *bindingSection, ExportSection *exportSection)
|
||||
: bindingSection(bindingSection), exportSection(exportSection) {}
|
||||
|
||||
uint32_t getSize() const override { return sizeof(dyld_info_command); }
|
||||
|
||||
|
@ -71,13 +74,14 @@ public:
|
|||
c->bind_off = bindingSection->getFileOffset();
|
||||
c->bind_size = bindingSection->getFileSize();
|
||||
}
|
||||
c->export_off = exportOff;
|
||||
c->export_size = exportSize;
|
||||
if (exportSection->isNeeded()) {
|
||||
c->export_off = exportSection->getFileOffset();
|
||||
c->export_size = exportSection->getFileSize();
|
||||
}
|
||||
}
|
||||
|
||||
BindingSection *bindingSection;
|
||||
uint64_t exportOff = 0;
|
||||
uint64_t exportSize = 0;
|
||||
ExportSection *exportSection;
|
||||
};
|
||||
|
||||
class LCDysymtab : public LoadCommand {
|
||||
|
@ -208,6 +212,30 @@ private:
|
|||
StringRef path;
|
||||
};
|
||||
|
||||
class LCIdDylib : public LoadCommand {
|
||||
public:
|
||||
LCIdDylib(StringRef name) : name(name) {}
|
||||
|
||||
uint32_t getSize() const override {
|
||||
return alignTo(sizeof(dylib_command) + name.size() + 1, 8);
|
||||
}
|
||||
|
||||
void writeTo(uint8_t *buf) const override {
|
||||
auto *c = reinterpret_cast<dylib_command *>(buf);
|
||||
buf += sizeof(dylib_command);
|
||||
|
||||
c->cmd = LC_ID_DYLIB;
|
||||
c->cmdsize = getSize();
|
||||
c->dylib.name = sizeof(dylib_command);
|
||||
|
||||
memcpy(buf, name.data(), name.size());
|
||||
buf[name.size()] = '\0';
|
||||
}
|
||||
|
||||
private:
|
||||
StringRef name;
|
||||
};
|
||||
|
||||
class LCLoadDylinker : public LoadCommand {
|
||||
public:
|
||||
uint32_t getSize() const override {
|
||||
|
@ -253,6 +281,7 @@ public:
|
|||
{segment_names::linkEdit,
|
||||
{
|
||||
section_names::binding,
|
||||
section_names::export_,
|
||||
section_names::symbolTable,
|
||||
section_names::stringTable,
|
||||
}},
|
||||
|
@ -309,12 +338,23 @@ void Writer::scanRelocations() {
|
|||
}
|
||||
|
||||
void Writer::createLoadCommands() {
|
||||
headerSection->addLoadCommand(make<LCDyldInfo>(bindingSection));
|
||||
headerSection->addLoadCommand(make<LCLoadDylinker>());
|
||||
headerSection->addLoadCommand(
|
||||
make<LCDyldInfo>(bindingSection, exportSection));
|
||||
headerSection->addLoadCommand(
|
||||
make<LCSymtab>(symtabSection, stringTableSection));
|
||||
headerSection->addLoadCommand(make<LCDysymtab>());
|
||||
|
||||
switch (config->outputType) {
|
||||
case MH_EXECUTE:
|
||||
headerSection->addLoadCommand(make<LCMain>());
|
||||
headerSection->addLoadCommand(make<LCLoadDylinker>());
|
||||
break;
|
||||
case MH_DYLIB:
|
||||
headerSection->addLoadCommand(make<LCIdDylib>(config->installName));
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("unhandled output file type");
|
||||
}
|
||||
|
||||
uint8_t segIndex = 0;
|
||||
for (OutputSegment *seg : outputSegments) {
|
||||
|
@ -343,7 +383,17 @@ void Writer::createHiddenSections() {
|
|||
bindingSection = createInputSection<BindingSection>();
|
||||
stringTableSection = createInputSection<StringTableSection>();
|
||||
symtabSection = createInputSection<SymtabSection>(*stringTableSection);
|
||||
exportSection = createInputSection<ExportSection>();
|
||||
|
||||
switch (config->outputType) {
|
||||
case MH_EXECUTE:
|
||||
createInputSection<PageZeroSection>();
|
||||
break;
|
||||
case MH_DYLIB:
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("unhandled output file type");
|
||||
}
|
||||
}
|
||||
|
||||
void Writer::sortSections() {
|
||||
|
@ -429,6 +479,7 @@ void Writer::run() {
|
|||
|
||||
// Fill __LINKEDIT contents.
|
||||
bindingSection->finalizeContents();
|
||||
exportSection->finalizeContents();
|
||||
symtabSection->finalizeContents();
|
||||
|
||||
// Now that __LINKEDIT is filled out, do a proper calculation of its
|
||||
|
|
|
@ -1,175 +0,0 @@
|
|||
## This yaml file was originally generated from linking the following source
|
||||
## input with ld64:
|
||||
##
|
||||
## .section __TEXT,__cstring
|
||||
## .globl _goodbye_world
|
||||
##
|
||||
## _goodbye_world:
|
||||
## .asciz "Goodbye world!\n"
|
||||
##
|
||||
## When lld can produce dylibs, we will use that instead for our test setup.
|
||||
|
||||
--- !mach-o
|
||||
FileHeader:
|
||||
magic: 0xFEEDFACF
|
||||
cputype: 0x01000007
|
||||
cpusubtype: 0x00000003
|
||||
filetype: 0x00000006
|
||||
ncmds: 11
|
||||
sizeofcmds: 624
|
||||
flags: 0x00100085
|
||||
reserved: 0x00000000
|
||||
LoadCommands:
|
||||
- cmd: LC_SEGMENT_64
|
||||
cmdsize: 232
|
||||
segname: __TEXT
|
||||
vmaddr: 0
|
||||
vmsize: 4096
|
||||
fileoff: 0
|
||||
filesize: 4096
|
||||
maxprot: 5
|
||||
initprot: 5
|
||||
nsects: 2
|
||||
flags: 0
|
||||
Sections:
|
||||
- sectname: __text
|
||||
segname: __TEXT
|
||||
addr: 0x0000000000000FF0
|
||||
size: 0
|
||||
offset: 0x00000FF0
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x80000400
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
content: ''
|
||||
- sectname: __cstring
|
||||
segname: __TEXT
|
||||
addr: 0x0000000000000FF0
|
||||
size: 16
|
||||
offset: 0x00000FF0
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000002
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
content: 476F6F6462796520776F726C64210A00
|
||||
- cmd: LC_SEGMENT_64
|
||||
cmdsize: 72
|
||||
segname: __LINKEDIT
|
||||
vmaddr: 4096
|
||||
vmsize: 4096
|
||||
fileoff: 4096
|
||||
filesize: 72
|
||||
maxprot: 1
|
||||
initprot: 1
|
||||
nsects: 0
|
||||
flags: 0
|
||||
- cmd: LC_ID_DYLIB
|
||||
cmdsize: 64
|
||||
dylib:
|
||||
name: 24
|
||||
timestamp: 1
|
||||
current_version: 0
|
||||
compatibility_version: 0
|
||||
PayloadString: '@executable_path/libgoodbye.dylib'
|
||||
ZeroPadBytes: 7
|
||||
- cmd: LC_DYLD_INFO_ONLY
|
||||
cmdsize: 48
|
||||
rebase_off: 0
|
||||
rebase_size: 0
|
||||
bind_off: 0
|
||||
bind_size: 0
|
||||
weak_bind_off: 0
|
||||
weak_bind_size: 0
|
||||
lazy_bind_off: 0
|
||||
lazy_bind_size: 0
|
||||
export_off: 4096
|
||||
export_size: 24
|
||||
- cmd: LC_SYMTAB
|
||||
cmdsize: 24
|
||||
symoff: 4128
|
||||
nsyms: 1
|
||||
stroff: 4144
|
||||
strsize: 24
|
||||
- cmd: LC_DYSYMTAB
|
||||
cmdsize: 80
|
||||
ilocalsym: 0
|
||||
nlocalsym: 0
|
||||
iextdefsym: 0
|
||||
nextdefsym: 1
|
||||
iundefsym: 1
|
||||
nundefsym: 0
|
||||
tocoff: 0
|
||||
ntoc: 0
|
||||
modtaboff: 0
|
||||
nmodtab: 0
|
||||
extrefsymoff: 0
|
||||
nextrefsyms: 0
|
||||
indirectsymoff: 0
|
||||
nindirectsyms: 0
|
||||
extreloff: 0
|
||||
nextrel: 0
|
||||
locreloff: 0
|
||||
nlocrel: 0
|
||||
- cmd: LC_UUID
|
||||
cmdsize: 24
|
||||
uuid: EA09CDDC-A3EA-3EB9-8C4F-334077FE6E5A
|
||||
- cmd: LC_BUILD_VERSION
|
||||
cmdsize: 32
|
||||
platform: 1
|
||||
minos: 659200
|
||||
sdk: 659200
|
||||
ntools: 1
|
||||
Tools:
|
||||
- tool: 3
|
||||
version: 34734080
|
||||
- cmd: LC_SOURCE_VERSION
|
||||
cmdsize: 16
|
||||
version: 0
|
||||
- cmd: LC_FUNCTION_STARTS
|
||||
cmdsize: 16
|
||||
dataoff: 4120
|
||||
datasize: 8
|
||||
- cmd: LC_DATA_IN_CODE
|
||||
cmdsize: 16
|
||||
dataoff: 4128
|
||||
datasize: 0
|
||||
LinkEditData:
|
||||
ExportTrie:
|
||||
TerminalSize: 0
|
||||
NodeOffset: 0
|
||||
Name: ''
|
||||
Flags: 0x0000000000000000
|
||||
Address: 0x0000000000000000
|
||||
Other: 0x0000000000000000
|
||||
ImportName: ''
|
||||
Children:
|
||||
- TerminalSize: 3
|
||||
NodeOffset: 18
|
||||
Name: _goodbye_world
|
||||
Flags: 0x0000000000000000
|
||||
Address: 0x0000000000000FF0
|
||||
Other: 0x0000000000000000
|
||||
ImportName: ''
|
||||
NameList:
|
||||
- n_strx: 2
|
||||
n_type: 0x0F
|
||||
n_sect: 2
|
||||
n_desc: 0
|
||||
n_value: 4080
|
||||
StringTable:
|
||||
- ' '
|
||||
- _goodbye_world
|
||||
- ''
|
||||
- ''
|
||||
- ''
|
||||
- ''
|
||||
- ''
|
||||
- ''
|
||||
- ''
|
||||
...
|
|
@ -1,169 +0,0 @@
|
|||
## This yaml file was originally generated from linking the following source
|
||||
## input with ld64:
|
||||
##
|
||||
## .section __TEXT,__cstring
|
||||
## .globl _hello_world
|
||||
##
|
||||
## _hello_world:
|
||||
## .asciz "Hello world!\n"
|
||||
##
|
||||
## When lld can produce dylibs, we will use that instead for our test setup.
|
||||
|
||||
--- !mach-o
|
||||
FileHeader:
|
||||
magic: 0xFEEDFACF
|
||||
cputype: 0x01000007
|
||||
cpusubtype: 0x00000003
|
||||
filetype: 0x00000006
|
||||
ncmds: 11
|
||||
sizeofcmds: 616
|
||||
flags: 0x00100085
|
||||
reserved: 0x00000000
|
||||
LoadCommands:
|
||||
- cmd: LC_SEGMENT_64
|
||||
cmdsize: 232
|
||||
segname: __TEXT
|
||||
vmaddr: 0
|
||||
vmsize: 4096
|
||||
fileoff: 0
|
||||
filesize: 4096
|
||||
maxprot: 5
|
||||
initprot: 5
|
||||
nsects: 2
|
||||
flags: 0
|
||||
Sections:
|
||||
- sectname: __text
|
||||
segname: __TEXT
|
||||
addr: 0x0000000000000FF2
|
||||
size: 0
|
||||
offset: 0x00000FF2
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x80000400
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
content: ''
|
||||
- sectname: __cstring
|
||||
segname: __TEXT
|
||||
addr: 0x0000000000000FF2
|
||||
size: 14
|
||||
offset: 0x00000FF2
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000002
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
content: 48656C6C6F20776F726C64210A00
|
||||
- cmd: LC_SEGMENT_64
|
||||
cmdsize: 72
|
||||
segname: __LINKEDIT
|
||||
vmaddr: 4096
|
||||
vmsize: 4096
|
||||
fileoff: 4096
|
||||
filesize: 64
|
||||
maxprot: 1
|
||||
initprot: 1
|
||||
nsects: 0
|
||||
flags: 0
|
||||
- cmd: LC_ID_DYLIB
|
||||
cmdsize: 56
|
||||
dylib:
|
||||
name: 24
|
||||
timestamp: 1
|
||||
current_version: 0
|
||||
compatibility_version: 0
|
||||
PayloadString: '@executable_path/libhello.dylib'
|
||||
ZeroPadBytes: 1
|
||||
- cmd: LC_DYLD_INFO_ONLY
|
||||
cmdsize: 48
|
||||
rebase_off: 0
|
||||
rebase_size: 0
|
||||
bind_off: 0
|
||||
bind_size: 0
|
||||
weak_bind_off: 0
|
||||
weak_bind_size: 0
|
||||
lazy_bind_off: 0
|
||||
lazy_bind_size: 0
|
||||
export_off: 4096
|
||||
export_size: 24
|
||||
- cmd: LC_SYMTAB
|
||||
cmdsize: 24
|
||||
symoff: 4128
|
||||
nsyms: 1
|
||||
stroff: 4144
|
||||
strsize: 16
|
||||
- cmd: LC_DYSYMTAB
|
||||
cmdsize: 80
|
||||
ilocalsym: 0
|
||||
nlocalsym: 0
|
||||
iextdefsym: 0
|
||||
nextdefsym: 1
|
||||
iundefsym: 1
|
||||
nundefsym: 0
|
||||
tocoff: 0
|
||||
ntoc: 0
|
||||
modtaboff: 0
|
||||
nmodtab: 0
|
||||
extrefsymoff: 0
|
||||
nextrefsyms: 0
|
||||
indirectsymoff: 0
|
||||
nindirectsyms: 0
|
||||
extreloff: 0
|
||||
nextrel: 0
|
||||
locreloff: 0
|
||||
nlocrel: 0
|
||||
- cmd: LC_UUID
|
||||
cmdsize: 24
|
||||
uuid: 4826226E-9210-3984-A388-D5BD6D6DB368
|
||||
- cmd: LC_BUILD_VERSION
|
||||
cmdsize: 32
|
||||
platform: 1
|
||||
minos: 659200
|
||||
sdk: 659200
|
||||
ntools: 1
|
||||
Tools:
|
||||
- tool: 3
|
||||
version: 34734080
|
||||
- cmd: LC_SOURCE_VERSION
|
||||
cmdsize: 16
|
||||
version: 0
|
||||
- cmd: LC_FUNCTION_STARTS
|
||||
cmdsize: 16
|
||||
dataoff: 4120
|
||||
datasize: 8
|
||||
- cmd: LC_DATA_IN_CODE
|
||||
cmdsize: 16
|
||||
dataoff: 4128
|
||||
datasize: 0
|
||||
LinkEditData:
|
||||
ExportTrie:
|
||||
TerminalSize: 0
|
||||
NodeOffset: 0
|
||||
Name: ''
|
||||
Flags: 0x0000000000000000
|
||||
Address: 0x0000000000000000
|
||||
Other: 0x0000000000000000
|
||||
ImportName: ''
|
||||
Children:
|
||||
- TerminalSize: 3
|
||||
NodeOffset: 16
|
||||
Name: _hello_world
|
||||
Flags: 0x0000000000000000
|
||||
Address: 0x0000000000000FF2
|
||||
Other: 0x0000000000000000
|
||||
ImportName: ''
|
||||
NameList:
|
||||
- n_strx: 2
|
||||
n_type: 0x0F
|
||||
n_sect: 2
|
||||
n_desc: 0
|
||||
n_value: 4082
|
||||
StringTable:
|
||||
- ' '
|
||||
- _hello_world
|
||||
- ''
|
||||
...
|
|
@ -0,0 +1,5 @@
|
|||
.section __TEXT,__cstring
|
||||
.globl _goodbye_world
|
||||
|
||||
_goodbye_world:
|
||||
.asciz "Goodbye world!\n"
|
|
@ -0,0 +1,5 @@
|
|||
.section __TEXT,__cstring
|
||||
.globl _hello_world
|
||||
|
||||
_hello_world:
|
||||
.asciz "Hello world!\n"
|
|
@ -0,0 +1,35 @@
|
|||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
||||
|
||||
# RUN: lld -flavor darwinnew -dylib -install_name @executable_path/libfoo.dylib \
|
||||
# RUN: %t.o -o %t.dylib
|
||||
# RUN: llvm-objdump --macho --dylib-id %t.dylib | FileCheck %s
|
||||
# CHECK: @executable_path/libfoo.dylib
|
||||
|
||||
## If we are building a dylib, we shouldn't error out even if we are passed
|
||||
## a flag for a missing entry symbol (since dylibs don't have entry symbols).
|
||||
## Also check that we come up with the right install name if one isn't
|
||||
## specified.
|
||||
# RUN: lld -flavor darwinnew -dylib %t.o -o %t.defaultInstallName.dylib -e missing_entry
|
||||
# RUN: obj2yaml %t.defaultInstallName.dylib | FileCheck %s -DOUTPUT=%t.defaultInstallName.dylib --check-prefix=DEFAULT-INSTALL-NAME
|
||||
# DEFAULT-INSTALL-NAME: [[OUTPUT]]
|
||||
|
||||
## Check for the absence of load commands / segments that should not be in a
|
||||
## dylib.
|
||||
# RUN: llvm-objdump --macho --all-headers %t.dylib | FileCheck %s --check-prefix=NCHECK
|
||||
# NCHECK-NOT: cmd LC_LOAD_DYLINKER
|
||||
# NCHECK-NOT: cmd LC_MAIN
|
||||
# NCHECK-NOT: segname __PAGEZERO
|
||||
|
||||
# RUN: llvm-objdump --syms --exports-trie %t.dylib | \
|
||||
# RUN: FileCheck %s --check-prefix=EXPORTS
|
||||
# EXPORTS-LABEL: SYMBOL TABLE:
|
||||
# EXPORTS: [[#%x, HELLO_WORLD_ADDR:]] {{.*}} _hello_world
|
||||
# EXPORTS-LABEL: Exports trie:
|
||||
# EXPORTS: 0x{{0*}}[[#%X, HELLO_WORLD_ADDR]] _hello_world
|
||||
|
||||
.section __TEXT,__cstring
|
||||
.globl _hello_world
|
||||
|
||||
_hello_world:
|
||||
.asciz "Hello world!\n"
|
|
@ -1,7 +1,13 @@
|
|||
# REQUIRES: x86
|
||||
# RUN: mkdir -p %t
|
||||
# RUN: yaml2obj %p/Inputs/hello-dylib.yaml -o %t/libhello.dylib
|
||||
# RUN: yaml2obj %p/Inputs/goodbye-dylib.yaml -o %t/libgoodbye.dylib
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %p/Inputs/libhello.s \
|
||||
# RUN: -o %t/libhello.o
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %p/Inputs/libgoodbye.s \
|
||||
# RUN: -o %t/libgoodbye.o
|
||||
# RUN: lld -flavor darwinnew -dylib -install_name \
|
||||
# RUN: @executable_path/libhello.dylib %t/libhello.o -o %t/libhello.dylib
|
||||
# RUN: lld -flavor darwinnew -dylib -install_name \
|
||||
# RUN: @executable_path/libgoodbye.dylib %t/libgoodbye.o -o %t/libgoodbye.dylib
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/dylink.o
|
||||
# RUN: lld -flavor darwinnew -o %t/dylink -Z -L%t -lhello -lgoodbye %t/dylink.o
|
||||
# RUN: llvm-objdump --bind -d %t/dylink | FileCheck %s
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
||||
# RUN: lld -flavor darwinnew -o %t %t.o
|
||||
# RUN: obj2yaml %t | FileCheck %s
|
||||
|
||||
# Check for the presence of a couple of load commands that are essential for
|
||||
# a working binary.
|
||||
## Check for the presence of load commands that are essential for a working
|
||||
## executable.
|
||||
# RUN: llvm-objdump --macho --all-headers %t | FileCheck %s
|
||||
# CHECK-DAG: cmd LC_DYLD_INFO_ONLY
|
||||
# CHECK-DAG: cmd LC_SYMTAB
|
||||
# CHECK-DAG: cmd LC_DYSYMTAB
|
||||
# CHECK-DAG: cmd LC_MAIN
|
||||
# CHECK-DAG: cmd LC_LOAD_DYLINKER
|
||||
|
||||
# CHECK-DAG: cmd: LC_DYLD_INFO_ONLY
|
||||
# CHECK-DAG: cmd: LC_SYMTAB
|
||||
# CHECK-DAG: cmd: LC_DYSYMTAB
|
||||
## Check for the absence of load commands that should not be in an executable.
|
||||
# RUN: llvm-objdump --macho --all-headers %t | FileCheck %s --check-prefix=NCHECK
|
||||
# NCHECK-NOT: cmd: LC_ID_DYLIB
|
||||
|
||||
.text
|
||||
.global _main
|
||||
|
|
|
@ -14,41 +14,10 @@
|
|||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: Value:
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Symbol {
|
||||
# CHECK-NEXT: Name: bar
|
||||
# CHECK-NEXT: Extern
|
||||
# CHECK-NEXT: Type: Section (0xE)
|
||||
# CHECK-NEXT: Section: __text (0x1)
|
||||
# CHECK-NEXT: RefType:
|
||||
# CHECK-NEXT: Flags [ (0x0)
|
||||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: Value:
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Symbol {
|
||||
# CHECK-NEXT: Name: foo
|
||||
# CHECK-NEXT: Extern
|
||||
# CHECK-NEXT: Type: Section (0xE)
|
||||
# CHECK-NEXT: Section: __data
|
||||
# CHECK-NEXT: RefType:
|
||||
# CHECK-NEXT: Flags [ (0x0)
|
||||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: Value:
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: ]
|
||||
|
||||
.data
|
||||
.global foo
|
||||
foo:
|
||||
.asciz "Hello world!\n"
|
||||
|
||||
.text
|
||||
.global bar
|
||||
.global _main
|
||||
|
||||
_main:
|
||||
mov $0, %rax
|
||||
ret
|
||||
|
||||
bar:
|
||||
mov $2, %rax
|
||||
ret
|
||||
|
|
Loading…
Reference in New Issue