diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -495,6 +495,7 @@ case OPT_Z: case OPT_arch: case OPT_syslibroot: + case OPT_sectcreate: // handled elsewhere break; default: @@ -524,6 +525,15 @@ createSyntheticSections(); symtab->addDSOHandle(in.header); + for (opt::Arg *arg : args.filtered(OPT_sectcreate)) { + StringRef segName = arg->getValue(0); + StringRef sectName = arg->getValue(1); + StringRef fileName = arg->getValue(2); + Optional buffer = readFile(fileName); + if (buffer) + inputFiles.push_back(make(*buffer, segName, sectName)); + } + // Initialize InputSections. for (InputFile *file : inputFiles) { for (SubsectionMap &map : file->subsections) { diff --git a/lld/MachO/InputFiles.h b/lld/MachO/InputFiles.h --- a/lld/MachO/InputFiles.h +++ b/lld/MachO/InputFiles.h @@ -40,6 +40,7 @@ ObjKind, DylibKind, ArchiveKind, + OpaqueKind, }; virtual ~InputFile() = default; @@ -72,6 +73,14 @@ static bool classof(const InputFile *f) { return f->kind() == ObjKind; } }; +// command-line -sectcreate file +class OpaqueFile : public InputFile { +public: + explicit OpaqueFile(MemoryBufferRef mb, StringRef segName, + StringRef sectName); + static bool classof(const InputFile *f) { return f->kind() == OpaqueKind; } +}; + // .dylib file class DylibFile : public InputFile { public: diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -301,6 +301,18 @@ } } +OpaqueFile::OpaqueFile(MemoryBufferRef mb, StringRef segName, + StringRef sectName) + : InputFile(OpaqueKind, mb) { + InputSection *isec = make(); + isec->file = this; + isec->name = sectName.take_front(16); + isec->segname = segName.take_front(16); + const auto *buf = reinterpret_cast(mb.getBufferStart()); + isec->data = {buf, mb.getBufferSize()}; + subsections.push_back({{0, isec}}); +} + ObjFile::ObjFile(MemoryBufferRef mb) : InputFile(ObjKind, mb) { auto *buf = reinterpret_cast(mb.getBufferStart()); auto *hdr = reinterpret_cast(mb.getBufferStart()); diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -156,7 +156,6 @@ def sectcreate : MultiArg<["-"], "sectcreate", 3>, MetaVarName<"
">, HelpText<"Create
in from the contents of ">, - Flags<[HelpHidden]>, Group; def segcreate : MultiArg<["-"], "segcreate", 3>, MetaVarName<"
">, diff --git a/lld/test/MachO/sectcreate.s b/lld/test/MachO/sectcreate.s new file mode 100644 --- /dev/null +++ b/lld/test/MachO/sectcreate.s @@ -0,0 +1,31 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o +# RUN: echo "-sectcreate 1.1" >%t1 +# RUN: echo "-sectcreate 1.2" >%t2 +# RUN: echo "-sectcreate 2" >%t3 +# RUN: lld -flavor darwinnew -Z \ +# RUN: -sectcreate SEG SEC1 %t1 \ +# RUN: -sectcreate SEG SEC2 %t3 \ +# RUN: -sectcreate SEG SEC1 %t2 \ +# RUN: -o %t %t.o +# RUN: llvm-objdump -s %t | FileCheck %s + +# CHECK: Contents of section __text: +# CHECK: Contents of section __data: +# CHECK: my string!. +# CHECK: Contents of section SEC1: +# CHECK: -sectcreate 1.1. +# CHECK: -sectcreate 1.2. +# CHECK: Contents of section SEC2: +# CHECK: -sectcreate 2. + +.text +.global _main +_main: + mov $0, %eax + ret + +.data +.global my_string +my_string: + .string "my string!"