Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/ObjectYAML/MachOEmitter.cpp
//===- yaml2macho - Convert YAML to a Mach object file --------------------===// | //===- yaml2macho - Convert YAML to a Mach object file --------------------===// | ||||||||
// | // | ||||||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||||||
// See https://llvm.org/LICENSE.txt for license information. | // See https://llvm.org/LICENSE.txt for license information. | ||||||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||||||
// | // | ||||||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||||
/// | /// | ||||||||
/// \file | /// \file | ||||||||
/// The Mach component of yaml2obj. | /// The Mach component of yaml2obj. | ||||||||
/// | /// | ||||||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||||
#include "llvm/BinaryFormat/MachO.h" | #include "llvm/BinaryFormat/MachO.h" | ||||||||
#include "llvm/ObjectYAML/DWARFEmitter.h" | #include "llvm/ObjectYAML/DWARFEmitter.h" | ||||||||
#include "llvm/ObjectYAML/DWARFYAML.h" | |||||||||
#include "llvm/ObjectYAML/ObjectYAML.h" | #include "llvm/ObjectYAML/ObjectYAML.h" | ||||||||
#include "llvm/ObjectYAML/yaml2obj.h" | #include "llvm/ObjectYAML/yaml2obj.h" | ||||||||
#include "llvm/Support/Errc.h" | #include "llvm/Support/Errc.h" | ||||||||
#include "llvm/Support/Error.h" | #include "llvm/Support/Error.h" | ||||||||
#include "llvm/Support/LEB128.h" | #include "llvm/Support/LEB128.h" | ||||||||
#include "llvm/Support/YAMLTraits.h" | #include "llvm/Support/YAMLTraits.h" | ||||||||
#include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | ||||||||
▲ Show 20 Lines • Show All 237 Lines • ▼ Show 20 Lines | #include "llvm/BinaryFormat/MachO.def" | ||||||||
auto BytesRemaining = LC.Data.load_command_data.cmdsize - BytesWritten; | auto BytesRemaining = LC.Data.load_command_data.cmdsize - BytesWritten; | ||||||||
if (BytesRemaining > 0) { | if (BytesRemaining > 0) { | ||||||||
ZeroFillBytes(OS, BytesRemaining); | ZeroFillBytes(OS, BytesRemaining); | ||||||||
} | } | ||||||||
} | } | ||||||||
} | } | ||||||||
Error MachOWriter::writeSectionData(raw_ostream &OS) { | Error MachOWriter::writeSectionData(raw_ostream &OS) { | ||||||||
// There might be DWARF sections and they might be interlinked. We use | |||||||||
// DWARFState to get them interlinked. | |||||||||
jhendersonUnsubmitted Done ReplyInline Actions
jhenderson: | |||||||||
Optional<DWARFYAML::DWARFState> DWARFState; | |||||||||
if (!Obj.DWARF.isEmpty()) { | |||||||||
Expected<DWARFYAML::DWARFState> DSOrErr = | |||||||||
DWARFYAML::DWARFState::create(Obj.DWARF); | |||||||||
if (DSOrErr) | |||||||||
DWARFState.emplace(*DSOrErr); | |||||||||
else | |||||||||
return DSOrErr.takeError(); | |||||||||
} | |||||||||
for (auto &LC : Obj.LoadCommands) { | for (auto &LC : Obj.LoadCommands) { | ||||||||
switch (LC.Data.load_command_data.cmd) { | switch (LC.Data.load_command_data.cmd) { | ||||||||
case MachO::LC_SEGMENT: | case MachO::LC_SEGMENT: | ||||||||
case MachO::LC_SEGMENT_64: | case MachO::LC_SEGMENT_64: | ||||||||
uint64_t segOff = is64Bit ? LC.Data.segment_command_64_data.fileoff | uint64_t segOff = is64Bit ? LC.Data.segment_command_64_data.fileoff | ||||||||
: LC.Data.segment_command_data.fileoff; | : LC.Data.segment_command_data.fileoff; | ||||||||
if (0 == | if (0 == | ||||||||
strncmp(&LC.Data.segment_command_data.segname[0], "__LINKEDIT", 16)) { | strncmp(&LC.Data.segment_command_data.segname[0], "__LINKEDIT", 16)) { | ||||||||
FoundLinkEditSeg = true; | FoundLinkEditSeg = true; | ||||||||
writeLinkEditData(OS); | writeLinkEditData(OS); | ||||||||
} | } | ||||||||
for (auto &Sec : LC.Sections) { | for (auto &Sec : LC.Sections) { | ||||||||
ZeroToOffset(OS, Sec.offset); | ZeroToOffset(OS, Sec.offset); | ||||||||
// Zero Fill any data between the end of the last thing we wrote and the | // Zero Fill any data between the end of the last thing we wrote and the | ||||||||
// start of this section. | // start of this section. | ||||||||
if (OS.tell() - fileStart > Sec.offset && Sec.offset != (uint32_t)0) | if (OS.tell() - fileStart > Sec.offset && Sec.offset != (uint32_t)0) | ||||||||
return createStringError( | return createStringError( | ||||||||
errc::invalid_argument, | errc::invalid_argument, | ||||||||
"wrote too much data somewhere, section offsets don't line up"); | "wrote too much data somewhere, section offsets don't line up"); | ||||||||
if (0 == strncmp(&Sec.segname[0], "__DWARF", sizeof(Sec.segname))) { | if (0 == strncmp(&Sec.segname[0], "__DWARF", sizeof(Sec.segname)) && | ||||||||
DWARFState) { | |||||||||
StringRef SectName(Sec.sectname, | StringRef SectName(Sec.sectname, | ||||||||
strnlen(Sec.sectname, sizeof(Sec.sectname))); | strnlen(Sec.sectname, sizeof(Sec.sectname))); | ||||||||
if (Obj.DWARF.getNonEmptySectionNames().count(SectName.substr(2))) { | const DWARFYAML::Data &DWARF = DWARFState->getDWARFData(); | ||||||||
if (DWARF.getNonEmptySectionNames().count(SectName.substr(2))) { | |||||||||
auto EmitFunc = | auto EmitFunc = | ||||||||
DWARFYAML::getDWARFEmitterByName(SectName.substr(2)); | DWARFYAML::getDWARFEmitterByName(SectName.substr(2)); | ||||||||
if (Error Err = EmitFunc(OS, Obj.DWARF)) | if (Error Err = EmitFunc(OS, *DWARFState)) | ||||||||
return Err; | return Err; | ||||||||
} | } | ||||||||
continue; | continue; | ||||||||
} | } | ||||||||
// Skip if it's a virtual section. | // Skip if it's a virtual section. | ||||||||
if (MachO::isVirtualSection(Sec.flags & MachO::SECTION_TYPE)) | if (MachO::isVirtualSection(Sec.flags & MachO::SECTION_TYPE)) | ||||||||
▲ Show 20 Lines • Show All 342 Lines • Show Last 20 Lines |