aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp')
-rw-r--r--llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp79
1 files changed, 54 insertions, 25 deletions
diff --git a/llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp b/llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp
index 56dd08df3b09..295098ed4118 100644
--- a/llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp
+++ b/llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp
@@ -16,9 +16,8 @@
#include "llvm/Support/ErrorHandling.h"
#include <memory>
-namespace llvm {
-namespace objcopy {
-namespace macho {
+using namespace llvm;
+using namespace llvm::objcopy::macho;
size_t MachOWriter::headerSize() const {
return Is64Bit ? sizeof(MachO::mach_header_64) : sizeof(MachO::mach_header);
@@ -108,6 +107,16 @@ size_t MachOWriter::totalSize() const {
LinkEditDataCommand.datasize);
}
+ if (O.LinkerOptimizationHintCommandIndex) {
+ const MachO::linkedit_data_command &LinkEditDataCommand =
+ O.LoadCommands[*O.LinkerOptimizationHintCommandIndex]
+ .MachOLoadCommand.linkedit_data_command_data;
+
+ if (LinkEditDataCommand.dataoff)
+ Ends.push_back(LinkEditDataCommand.dataoff +
+ LinkEditDataCommand.datasize);
+ }
+
if (O.FunctionStartsCommandIndex) {
const MachO::linkedit_data_command &LinkEditDataCommand =
O.LoadCommands[*O.FunctionStartsCommandIndex]
@@ -159,11 +168,12 @@ void MachOWriter::writeHeader() {
auto HeaderSize =
Is64Bit ? sizeof(MachO::mach_header_64) : sizeof(MachO::mach_header);
- memcpy(B.getBufferStart(), &Header, HeaderSize);
+ memcpy(Buf->getBufferStart(), &Header, HeaderSize);
}
void MachOWriter::writeLoadCommands() {
- uint8_t *Begin = B.getBufferStart() + headerSize();
+ uint8_t *Begin =
+ reinterpret_cast<uint8_t *>(Buf->getBufferStart()) + headerSize();
for (const LoadCommand &LC : O.LoadCommands) {
// Construct a load command.
MachO::macho_load_command MLC = LC.MachOLoadCommand;
@@ -257,11 +267,11 @@ void MachOWriter::writeSections() {
assert(Sec->Offset && "Section offset can not be zero");
assert((Sec->Size == Sec->Content.size()) && "Incorrect section size");
- memcpy(B.getBufferStart() + Sec->Offset, Sec->Content.data(),
+ memcpy(Buf->getBufferStart() + Sec->Offset, Sec->Content.data(),
Sec->Content.size());
for (size_t Index = 0; Index < Sec->Relocations.size(); ++Index) {
RelocationInfo RelocInfo = Sec->Relocations[Index];
- if (!RelocInfo.Scattered) {
+ if (!RelocInfo.Scattered && !RelocInfo.IsAddend) {
const uint32_t SymbolNum = RelocInfo.Extern
? (*RelocInfo.Symbol)->Index
: (*RelocInfo.Sec)->Index;
@@ -270,7 +280,7 @@ void MachOWriter::writeSections() {
if (IsLittleEndian != sys::IsLittleEndianHost)
MachO::swapStruct(
reinterpret_cast<MachO::any_relocation_info &>(RelocInfo.Info));
- memcpy(B.getBufferStart() + Sec->RelOff +
+ memcpy(Buf->getBufferStart() + Sec->RelOff +
Index * sizeof(MachO::any_relocation_info),
&RelocInfo.Info, sizeof(RelocInfo.Info));
}
@@ -300,7 +310,7 @@ void MachOWriter::writeStringTable() {
O.LoadCommands[*O.SymTabCommandIndex]
.MachOLoadCommand.symtab_command_data;
- uint8_t *StrTable = (uint8_t *)B.getBufferStart() + SymTabCommand.stroff;
+ uint8_t *StrTable = (uint8_t *)Buf->getBufferStart() + SymTabCommand.stroff;
LayoutBuilder.getStringTableBuilder().write(StrTable);
}
@@ -311,7 +321,7 @@ void MachOWriter::writeSymbolTable() {
O.LoadCommands[*O.SymTabCommandIndex]
.MachOLoadCommand.symtab_command_data;
- char *SymTable = (char *)B.getBufferStart() + SymTabCommand.symoff;
+ char *SymTable = (char *)Buf->getBufferStart() + SymTabCommand.symoff;
for (auto Iter = O.SymTable.Symbols.begin(), End = O.SymTable.Symbols.end();
Iter != End; Iter++) {
SymbolEntry *Sym = Iter->get();
@@ -330,7 +340,7 @@ void MachOWriter::writeRebaseInfo() {
const MachO::dyld_info_command &DyLdInfoCommand =
O.LoadCommands[*O.DyLdInfoCommandIndex]
.MachOLoadCommand.dyld_info_command_data;
- char *Out = (char *)B.getBufferStart() + DyLdInfoCommand.rebase_off;
+ char *Out = (char *)Buf->getBufferStart() + DyLdInfoCommand.rebase_off;
assert((DyLdInfoCommand.rebase_size == O.Rebases.Opcodes.size()) &&
"Incorrect rebase opcodes size");
memcpy(Out, O.Rebases.Opcodes.data(), O.Rebases.Opcodes.size());
@@ -342,7 +352,7 @@ void MachOWriter::writeBindInfo() {
const MachO::dyld_info_command &DyLdInfoCommand =
O.LoadCommands[*O.DyLdInfoCommandIndex]
.MachOLoadCommand.dyld_info_command_data;
- char *Out = (char *)B.getBufferStart() + DyLdInfoCommand.bind_off;
+ char *Out = (char *)Buf->getBufferStart() + DyLdInfoCommand.bind_off;
assert((DyLdInfoCommand.bind_size == O.Binds.Opcodes.size()) &&
"Incorrect bind opcodes size");
memcpy(Out, O.Binds.Opcodes.data(), O.Binds.Opcodes.size());
@@ -354,7 +364,7 @@ void MachOWriter::writeWeakBindInfo() {
const MachO::dyld_info_command &DyLdInfoCommand =
O.LoadCommands[*O.DyLdInfoCommandIndex]
.MachOLoadCommand.dyld_info_command_data;
- char *Out = (char *)B.getBufferStart() + DyLdInfoCommand.weak_bind_off;
+ char *Out = (char *)Buf->getBufferStart() + DyLdInfoCommand.weak_bind_off;
assert((DyLdInfoCommand.weak_bind_size == O.WeakBinds.Opcodes.size()) &&
"Incorrect weak bind opcodes size");
memcpy(Out, O.WeakBinds.Opcodes.data(), O.WeakBinds.Opcodes.size());
@@ -366,7 +376,7 @@ void MachOWriter::writeLazyBindInfo() {
const MachO::dyld_info_command &DyLdInfoCommand =
O.LoadCommands[*O.DyLdInfoCommandIndex]
.MachOLoadCommand.dyld_info_command_data;
- char *Out = (char *)B.getBufferStart() + DyLdInfoCommand.lazy_bind_off;
+ char *Out = (char *)Buf->getBufferStart() + DyLdInfoCommand.lazy_bind_off;
assert((DyLdInfoCommand.lazy_bind_size == O.LazyBinds.Opcodes.size()) &&
"Incorrect lazy bind opcodes size");
memcpy(Out, O.LazyBinds.Opcodes.data(), O.LazyBinds.Opcodes.size());
@@ -378,7 +388,7 @@ void MachOWriter::writeExportInfo() {
const MachO::dyld_info_command &DyLdInfoCommand =
O.LoadCommands[*O.DyLdInfoCommandIndex]
.MachOLoadCommand.dyld_info_command_data;
- char *Out = (char *)B.getBufferStart() + DyLdInfoCommand.export_off;
+ char *Out = (char *)Buf->getBufferStart() + DyLdInfoCommand.export_off;
assert((DyLdInfoCommand.export_size == O.Exports.Trie.size()) &&
"Incorrect export trie size");
memcpy(Out, O.Exports.Trie.data(), O.Exports.Trie.size());
@@ -393,7 +403,7 @@ void MachOWriter::writeIndirectSymbolTable() {
.MachOLoadCommand.dysymtab_command_data;
uint32_t *Out =
- (uint32_t *)(B.getBufferStart() + DySymTabCommand.indirectsymoff);
+ (uint32_t *)(Buf->getBufferStart() + DySymTabCommand.indirectsymoff);
for (const IndirectSymbolEntry &Sym : O.IndirectSymTable.Symbols) {
uint32_t Entry = (Sym.Symbol) ? (*Sym.Symbol)->Index : Sym.OriginalIndex;
if (IsLittleEndian != sys::IsLittleEndianHost)
@@ -407,7 +417,7 @@ void MachOWriter::writeLinkData(Optional<size_t> LCIndex, const LinkData &LD) {
return;
const MachO::linkedit_data_command &LinkEditDataCommand =
O.LoadCommands[*LCIndex].MachOLoadCommand.linkedit_data_command_data;
- char *Out = (char *)B.getBufferStart() + LinkEditDataCommand.dataoff;
+ char *Out = (char *)Buf->getBufferStart() + LinkEditDataCommand.dataoff;
assert((LinkEditDataCommand.datasize == LD.Data.size()) &&
"Incorrect data size");
memcpy(Out, LD.Data.data(), LD.Data.size());
@@ -421,6 +431,11 @@ void MachOWriter::writeDataInCodeData() {
return writeLinkData(O.DataInCodeCommandIndex, O.DataInCode);
}
+void MachOWriter::writeLinkerOptimizationHint() {
+ return writeLinkData(O.LinkerOptimizationHintCommandIndex,
+ O.LinkerOptimizationHint);
+}
+
void MachOWriter::writeFunctionStartsData() {
return writeLinkData(O.FunctionStartsCommandIndex, O.FunctionStarts);
}
@@ -490,6 +505,16 @@ void MachOWriter::writeTail() {
&MachOWriter::writeDataInCodeData);
}
+ if (O.LinkerOptimizationHintCommandIndex) {
+ const MachO::linkedit_data_command &LinkEditDataCommand =
+ O.LoadCommands[*O.LinkerOptimizationHintCommandIndex]
+ .MachOLoadCommand.linkedit_data_command_data;
+
+ if (LinkEditDataCommand.dataoff)
+ Queue.emplace_back(LinkEditDataCommand.dataoff,
+ &MachOWriter::writeLinkerOptimizationHint);
+ }
+
if (O.FunctionStartsCommandIndex) {
const MachO::linkedit_data_command &LinkEditDataCommand =
O.LoadCommands[*O.FunctionStartsCommandIndex]
@@ -511,16 +536,20 @@ void MachOWriter::writeTail() {
Error MachOWriter::finalize() { return LayoutBuilder.layout(); }
Error MachOWriter::write() {
- if (Error E = B.allocate(totalSize()))
- return E;
- memset(B.getBufferStart(), 0, totalSize());
+ size_t TotalSize = totalSize();
+ Buf = WritableMemoryBuffer::getNewMemBuffer(TotalSize);
+ if (!Buf)
+ return createStringError(errc::not_enough_memory,
+ "failed to allocate memory buffer of " +
+ Twine::utohexstr(TotalSize) + " bytes");
+ memset(Buf->getBufferStart(), 0, totalSize());
writeHeader();
writeLoadCommands();
writeSections();
writeTail();
- return B.commit();
-}
-} // end namespace macho
-} // end namespace objcopy
-} // end namespace llvm
+ // TODO: Implement direct writing to the output stream (without intermediate
+ // memory buffer Buf).
+ Out.write(Buf->getBufferStart(), Buf->getBufferSize());
+ return Error::success();
+}