[lld][Darwin] Add support for the -sectcreate option.
llvm-svn: 251183
This commit is contained in:
parent
25ca34c727
commit
b1b67f4daf
|
@ -151,6 +151,7 @@ public:
|
|||
typeNoAlloc, // Identifies non allocatable sections [ELF]
|
||||
typeGroupComdat, // Identifies a section group [ELF, COFF]
|
||||
typeGnuLinkOnce, // Identifies a gnu.linkonce section [ELF]
|
||||
typeSectCreate, // Created via the -sectcreate option [Darwin]
|
||||
};
|
||||
|
||||
// Permission bits for atoms and segments. The order of these values are
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace mach_o {
|
|||
class ArchHandler;
|
||||
class MachODylibFile;
|
||||
class MachOFile;
|
||||
class SectCreateFile;
|
||||
}
|
||||
|
||||
class MachOLinkingContext : public LinkingContext {
|
||||
|
@ -272,6 +273,10 @@ public:
|
|||
/// Add section alignment constraint on final layout.
|
||||
void addSectionAlignment(StringRef seg, StringRef sect, uint16_t align);
|
||||
|
||||
/// \brief Add a section based on a command-line sectcreate option.
|
||||
void addSectCreateSection(StringRef seg, StringRef sect,
|
||||
std::unique_ptr<MemoryBuffer> content);
|
||||
|
||||
/// Returns true if specified section had alignment constraints.
|
||||
bool sectionAligned(StringRef seg, StringRef sect, uint16_t &align) const;
|
||||
|
||||
|
@ -416,6 +421,7 @@ private:
|
|||
llvm::StringMap<std::vector<OrderFileNode>> _orderFiles;
|
||||
unsigned _orderFileEntries;
|
||||
File *_flatNamespaceFile;
|
||||
mach_o::SectCreateFile *_sectCreateFile = nullptr;
|
||||
};
|
||||
|
||||
} // end namespace lld
|
||||
|
|
|
@ -76,6 +76,7 @@ DefinedAtom::ContentPermissions DefinedAtom::permissions(ContentType type) {
|
|||
case typeGnuLinkOnce:
|
||||
case typeUnknown:
|
||||
case typeTempLTO:
|
||||
case typeSectCreate:
|
||||
return permUnknown;
|
||||
}
|
||||
llvm_unreachable("unknown content type");
|
||||
|
|
|
@ -822,7 +822,7 @@ bool DarwinLdDriver::parse(llvm::ArrayRef<const char *> args,
|
|||
}
|
||||
}
|
||||
|
||||
// Handle input files
|
||||
// Handle input files and sectcreate.
|
||||
for (auto &arg : parsedArgs) {
|
||||
bool upward;
|
||||
ErrorOr<StringRef> resolvedPath = StringRef();
|
||||
|
@ -876,6 +876,22 @@ bool DarwinLdDriver::parse(llvm::ArrayRef<const char *> args,
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
case OPT_sectcreate: {
|
||||
const char* seg = arg->getValue(0);
|
||||
const char* sect = arg->getValue(1);
|
||||
const char* fileName = arg->getValue(2);
|
||||
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> contentOrErr =
|
||||
MemoryBuffer::getFile(fileName);
|
||||
|
||||
if (!contentOrErr) {
|
||||
diagnostics << "error: can't open -sectcreate file " << fileName << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
ctx.addSectCreateSection(seg, sect, std::move(*contentOrErr));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -177,7 +177,10 @@ def arch : Separate<["-"], "arch">,
|
|||
HelpText<"Architecture to link">;
|
||||
def sectalign : MultiArg<["-"], "sectalign", 3>,
|
||||
MetaVarName<"<segname> <sectname> <alignment>">,
|
||||
HelpText<"alignment for segment/section">;
|
||||
HelpText<"Alignment for segment/section">;
|
||||
def sectcreate : MultiArg<["-"], "sectcreate", 3>,
|
||||
MetaVarName<"<segname> <sectname> <file>">,
|
||||
HelpText<"Create section <segname>/<sectname> from contents of <file>">;
|
||||
def image_base : Separate<["-"], "image_base">;
|
||||
def seg1addr : Separate<["-"], "seg1addr">, Alias<image_base>;
|
||||
def demangle : Flag<["-"], "demangle">,
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "FlatNamespaceFile.h"
|
||||
#include "MachONormalizedFile.h"
|
||||
#include "MachOPasses.h"
|
||||
#include "SectCreateFile.h"
|
||||
#include "lld/Core/ArchiveLibraryFile.h"
|
||||
#include "lld/Core/PassManager.h"
|
||||
#include "lld/Core/Reader.h"
|
||||
|
@ -749,6 +750,20 @@ void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect,
|
|||
_sectAligns.push_back(entry);
|
||||
}
|
||||
|
||||
void MachOLinkingContext::addSectCreateSection(
|
||||
StringRef seg, StringRef sect,
|
||||
std::unique_ptr<MemoryBuffer> content) {
|
||||
|
||||
if (!_sectCreateFile) {
|
||||
auto sectCreateFile = llvm::make_unique<mach_o::SectCreateFile>();
|
||||
_sectCreateFile = sectCreateFile.get();
|
||||
getNodes().push_back(llvm::make_unique<FileNode>(std::move(sectCreateFile)));
|
||||
}
|
||||
|
||||
assert(_sectCreateFile && "sectcreate file does not exist.");
|
||||
_sectCreateFile->addSection(seg, sect, std::move(content));
|
||||
}
|
||||
|
||||
bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect,
|
||||
uint16_t &align) const {
|
||||
for (const SectionAlign &entry : _sectAligns) {
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
//===---- lib/ReaderWriter/MachO/SectCreateFile.h ---------------*- c++ -*-===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLD_READER_WRITER_MACHO_SECTCREATE_FILE_H
|
||||
#define LLD_READER_WRITER_MACHO_SECTCREATE_FILE_H
|
||||
|
||||
#include "lld/Core/DefinedAtom.h"
|
||||
#include "lld/Core/Simple.h"
|
||||
#include "lld/ReaderWriter/MachOLinkingContext.h"
|
||||
|
||||
namespace lld {
|
||||
namespace mach_o {
|
||||
|
||||
//
|
||||
// A FlateNamespaceFile instance may be added as a resolution source of last
|
||||
// resort, depending on how -flat_namespace and -undefined are set.
|
||||
//
|
||||
class SectCreateFile : public File {
|
||||
public:
|
||||
|
||||
class SectCreateAtom : public SimpleDefinedAtom {
|
||||
public:
|
||||
SectCreateAtom(const File &file, StringRef segName, StringRef sectName,
|
||||
std::unique_ptr<MemoryBuffer> content)
|
||||
: SimpleDefinedAtom(file),
|
||||
_combinedName((segName + "/" + sectName).str()),
|
||||
_content(std::move(content)) {}
|
||||
|
||||
uint64_t size() const override { return _content->getBufferSize(); }
|
||||
|
||||
Scope scope() const override { return scopeGlobal; }
|
||||
|
||||
ContentType contentType() const override { return typeSectCreate; }
|
||||
|
||||
SectionChoice sectionChoice() const override { return sectionCustomRequired; }
|
||||
|
||||
StringRef customSectionName() const override { return _combinedName; }
|
||||
|
||||
DeadStripKind deadStrip() const override { return deadStripNever; }
|
||||
|
||||
ArrayRef<uint8_t> rawContent() const override {
|
||||
const uint8_t *data =
|
||||
reinterpret_cast<const uint8_t*>(_content->getBufferStart());
|
||||
return ArrayRef<uint8_t>(data, _content->getBufferSize());
|
||||
}
|
||||
|
||||
StringRef segmentName() const { return _segName; }
|
||||
StringRef sectionName() const { return _sectName; }
|
||||
|
||||
private:
|
||||
std::string _combinedName;
|
||||
StringRef _segName;
|
||||
StringRef _sectName;
|
||||
std::unique_ptr<MemoryBuffer> _content;
|
||||
};
|
||||
|
||||
SectCreateFile() : File("sectcreate", kindObject) {}
|
||||
|
||||
void addSection(StringRef seg, StringRef sect,
|
||||
std::unique_ptr<MemoryBuffer> content) {
|
||||
_definedAtoms.push_back(
|
||||
new (allocator()) SectCreateAtom(*this, seg, sect, std::move(content)));
|
||||
}
|
||||
|
||||
const AtomVector<DefinedAtom> &defined() const {
|
||||
return _definedAtoms;
|
||||
}
|
||||
|
||||
const AtomVector<UndefinedAtom> &undefined() const {
|
||||
return _noUndefinedAtoms;
|
||||
}
|
||||
|
||||
const AtomVector<SharedLibraryAtom> &sharedLibrary() const {
|
||||
return _noSharedLibraryAtoms;
|
||||
}
|
||||
|
||||
const AtomVector<AbsoluteAtom> &absolute() const {
|
||||
return _noAbsoluteAtoms;
|
||||
}
|
||||
|
||||
private:
|
||||
AtomVector<DefinedAtom> _definedAtoms;
|
||||
};
|
||||
|
||||
} // namespace mach_o
|
||||
} // namespace lld
|
||||
|
||||
#endif // LLD_READER_WRITER_MACHO_SECTCREATE_FILE_H
|
|
@ -437,6 +437,7 @@ template <> struct ScalarEnumerationTraits<lld::DefinedAtom::ContentType> {
|
|||
io.enumCase(value, "no-alloc", DefinedAtom::typeNoAlloc);
|
||||
io.enumCase(value, "group-comdat", DefinedAtom::typeGroupComdat);
|
||||
io.enumCase(value, "gnu-linkonce", DefinedAtom::typeGnuLinkOnce);
|
||||
io.enumCase(value, "sectcreate", DefinedAtom::typeSectCreate);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
hello
|
|
@ -0,0 +1,12 @@
|
|||
# RUN: lld -flavor darwin -r -arch x86_64 -o %t -sectcreate __DATA __data \
|
||||
# RUN: %p/Inputs/hw.raw_bytes -print_atoms | FileCheck %s
|
||||
|
||||
# CHECK: --- !native
|
||||
# CHECK: path: '<linker-internal>'
|
||||
# CHECK: defined-atoms:
|
||||
# CHECK: - scope: global
|
||||
# CHECK: type: sectcreate
|
||||
# CHECK: content: [ 68, 65, 6C, 6C, 6F, 0A ]
|
||||
# CHECK: section-choice: custom-required
|
||||
# CHECK: section-name: __DATA/__data
|
||||
# CHECK: dead-strip: never
|
Loading…
Reference in New Issue