mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-24 22:30:13 +00:00
001ba65375
@thakis pointed out that `mach_header` and `mach_header_64` actually have the same set of (used) fields, with the 64-bit version having extra padding. So we can access the fields we need using the single `mach_header` type instead of using templates to switch between the two. I also spotted a potential issue where hasObjCSection tries to parse a file w/o checking if it does indeed match the target arch... As such, I've added a quick magic number check to ensure we don't access invalid memory during `findCommand()`. Addresses PR50180. Reviewed By: #lld-macho, thakis Differential Revision: https://reviews.llvm.org/D101724
55 lines
1.7 KiB
C++
55 lines
1.7 KiB
C++
//===- ObjC.cpp -----------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "ObjC.h"
|
|
#include "InputFiles.h"
|
|
#include "InputSection.h"
|
|
#include "OutputSegment.h"
|
|
#include "Target.h"
|
|
|
|
#include "llvm/BinaryFormat/MachO.h"
|
|
|
|
using namespace llvm;
|
|
using namespace llvm::MachO;
|
|
using namespace lld;
|
|
using namespace lld::macho;
|
|
|
|
template <class LP> static bool hasObjCSection(MemoryBufferRef mb) {
|
|
using Section = typename LP::section;
|
|
|
|
auto *hdr =
|
|
reinterpret_cast<const typename LP::mach_header *>(mb.getBufferStart());
|
|
if (hdr->magic != LP::magic)
|
|
return false;
|
|
|
|
if (const auto *c =
|
|
findCommand<typename LP::segment_command>(hdr, LP::segmentLCType)) {
|
|
auto sectionHeaders =
|
|
ArrayRef<Section>{reinterpret_cast<const Section *>(c + 1), c->nsects};
|
|
for (const Section &sec : sectionHeaders) {
|
|
StringRef sectname(sec.sectname,
|
|
strnlen(sec.sectname, sizeof(sec.sectname)));
|
|
StringRef segname(sec.segname, strnlen(sec.segname, sizeof(sec.segname)));
|
|
if ((segname == segment_names::data &&
|
|
sectname == section_names::objcCatList) ||
|
|
(segname == segment_names::text &&
|
|
sectname == section_names::swift)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool macho::hasObjCSection(MemoryBufferRef mb) {
|
|
if (target->wordSize == 8)
|
|
return ::hasObjCSection<LP64>(mb);
|
|
else
|
|
return ::hasObjCSection<ILP32>(mb);
|
|
}
|