getLinkerOptionLoadCommand(const LoadCommandInfo &L) const;
MachO::version_min_command
getVersionMinLoadCommand(const LoadCommandInfo &L) const;
+ MachO::note_command
+ getNoteLoadCommand(const LoadCommandInfo &L) const;
MachO::dylib_command
getDylibIDLoadCommand(const LoadCommandInfo &L) const;
MachO::dyld_info_command
HANDLE_LOAD_COMMAND(LC_LINKER_OPTIMIZATION_HINT, 0x0000002Eu, linkedit_data_command)
HANDLE_LOAD_COMMAND(LC_VERSION_MIN_TVOS, 0x0000002Fu, version_min_command)
HANDLE_LOAD_COMMAND(LC_VERSION_MIN_WATCHOS, 0x00000030u, version_min_command)
+HANDLE_LOAD_COMMAND(LC_NOTE, 0x00000031u, note_command)
#endif
LOAD_COMMAND_STRUCT(twolevel_hints_command)
LOAD_COMMAND_STRUCT(uuid_command)
LOAD_COMMAND_STRUCT(version_min_command)
+LOAD_COMMAND_STRUCT(note_command)
#endif
uint32_t sdk; // X.Y.Z is encoded in nibbles xxxx.yy.zz
};
+ struct note_command {
+ uint32_t cmd; // LC_NOTE
+ uint32_t cmdsize; // sizeof(struct note_command)
+ char data_owner[16]; // owner name for this LC_NOTE
+ uint64_t offset; // file offset of this data
+ uint64_t size; // length of data region
+ };
+
struct dyld_info_command {
uint32_t cmd;
uint32_t cmdsize;
sys::swapByteOrder(C.sdk);
}
+ inline void swapStruct(note_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.offset);
+ sys::swapByteOrder(C.size);
+ }
+
inline void swapStruct(data_in_code_entry &C) {
sys::swapByteOrder(C.offset);
sys::swapByteOrder(C.length);
return Error::success();
}
+static Error checkNoteCommand(const MachOObjectFile &Obj,
+ const MachOObjectFile::LoadCommandInfo &Load,
+ uint32_t LoadCommandIndex,
+ std::list<MachOElement> &Elements) {
+ if (Load.C.cmdsize != sizeof(MachO::note_command))
+ return malformedError("load command " + Twine(LoadCommandIndex) +
+ " LC_NOTE has incorrect cmdsize");
+ MachO::note_command Nt = getStruct<MachO::note_command>(Obj, Load.Ptr);
+ uint64_t FileSize = Obj.getData().size();
+ if (Nt.offset > FileSize)
+ return malformedError("offset field of LC_NOTE command " +
+ Twine(LoadCommandIndex) + " extends "
+ "past the end of the file");
+ uint64_t BigSize = Nt.offset;
+ BigSize += Nt.size;
+ if (BigSize > FileSize)
+ return malformedError("size field plus offset field of LC_NOTE command " +
+ Twine(LoadCommandIndex) + " extends past the end of "
+ "the file");
+ if (Error Err = checkOverlappingElement(Elements, Nt.offset, Nt.size,
+ "LC_NOTE data"))
+ return Err;
+ return Error::success();
+}
+
static Error checkRpathCommand(const MachOObjectFile &Obj,
const MachOObjectFile::LoadCommandInfo &Load,
uint32_t LoadCommandIndex) {
if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
"LC_VERSION_MIN_WATCHOS")))
return;
+ } else if (Load.C.cmd == MachO::LC_NOTE) {
+ if ((Err = checkNoteCommand(*this, Load, I, Elements)))
+ return;
} else if (Load.C.cmd == MachO::LC_RPATH) {
if ((Err = checkRpathCommand(*this, Load, I)))
return;
return getStruct<MachO::version_min_command>(*this, L.Ptr);
}
+MachO::note_command
+MachOObjectFile::getNoteLoadCommand(const LoadCommandInfo &L) const {
+ return getStruct<MachO::note_command>(*this, L.Ptr);
+}
+
MachO::dylib_command
MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
return getStruct<MachO::dylib_command>(*this, L.Ptr);
IO.mapRequired("sdk", LoadCommand.sdk);
}
+void MappingTraits<MachO::note_command>::mapping(
+ IO &IO, MachO::note_command &LoadCommand) {
+
+ IO.mapRequired("data_owner", LoadCommand.data_owner);
+ IO.mapRequired("offset", LoadCommand.offset);
+ IO.mapRequired("size", LoadCommand.size);
+}
+
} // namespace llvm::yaml
} // namespace llvm
RUN: not llvm-objdump -macho -universal-headers %p/Inputs/macho-invalid-fat-arch-overlapheaders 2>&1 | FileCheck -check-prefix INVALID-FAT-ARCH-OVERLAPHEADERS %s
INVALID-FAT-ARCH-OVERLAPHEADERS: macho-invalid-fat-arch-overlapheaders': truncated or malformed fat file (cputype (7) cpusubtype (3) offset 12 overlaps universal headers)
+
+RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho-invalid-note 2>&1 | FileCheck -check-prefix INVALID-NOTE-COMMAND %s
+INVALID-NOTE-COMMAND: macho-invalid-note': truncated or malformed object (size field plus offset field of LC_NOTE command 0 extends past the end of the file)
--- /dev/null
+# RUN: yaml2obj %s | obj2yaml | FileCheck %s
+
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACE
+ cputype: 0x00000007
+ cpusubtype: 0x00000003
+ filetype: 0x00000004
+ ncmds: 2
+ sizeofcmds: 192
+ flags: 0x00000000
+LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __TEXT
+ vmaddr: 4294967296
+ vmsize: 8192
+ fileoff: 0
+ filesize: 3099
+ maxprot: 7
+ initprot: 5
+ nsects: 1
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x0000000100001160
+ size: 3099
+ offset: 0x00001160
+ align: 4
+ reloff: 0x00000000
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x00000000
+ reserved2: 0x00000000
+ reserved3: 0x00000000
+ - cmd: LC_NOTE
+ cmdsize: 40
+ data_owner: DATA OWNER
+ offset: 220
+ size: 8
+...
+
+
+#CHECK: LoadCommands:
+#CHECK: - cmd: LC_NOTE
+#CHECK_NEXT: cmdsize: 40
+#CHECK_NEXT: data_owner: DATA OWNER
+#CHECK_NEXT: offset: 220
+#CHECK_NEXT: size: 8
// RUN: | FileCheck %s -check-prefix=NON_VERBOSE
// RUN: llvm-objdump -p %p/Inputs/codesig.macho-x86_64 \
// RUN: | FileCheck %s -check-prefix=CODESIG
+// RUN: llvm-objdump -p %p/Inputs/note.macho-x86 \
+// RUN: | FileCheck %s -check-prefix=NOTE
CHECK: Mach header
CHECK: magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
CODESIG: cmdsize 16
CODESIG: dataoff 8496
CODESIG: datasize 64
+
+NOTE: cmd LC_NOTE
+NOTE: cmdsize 40
+NOTE: data_owner DATA OWNER
+NOTE: offset 68
+NOTE: size 8
outs() << "\n";
}
+static void PrintNoteLoadCommand(MachO::note_command Nt) {
+ outs() << " cmd LC_NOTE\n";
+ outs() << " cmdsize " << Nt.cmdsize;
+ if (Nt.cmdsize != sizeof(struct MachO::note_command))
+ outs() << " Incorrect size\n";
+ else
+ outs() << "\n";
+ const char *d = Nt.data_owner;
+ outs() << "data_owner " << format("%.16s\n", d);
+ outs() << " offset " << Nt.offset << "\n";
+ outs() << " size " << Nt.size << "\n";
+}
+
static void PrintSourceVersionCommand(MachO::source_version_command sd) {
outs() << " cmd LC_SOURCE_VERSION\n";
outs() << " cmdsize " << sd.cmdsize;
Command.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
MachO::version_min_command Vd = Obj->getVersionMinLoadCommand(Command);
PrintVersionMinLoadCommand(Vd);
+ } else if (Command.C.cmd == MachO::LC_NOTE) {
+ MachO::note_command Nt = Obj->getNoteLoadCommand(Command);
+ PrintNoteLoadCommand(Nt);
} else if (Command.C.cmd == MachO::LC_SOURCE_VERSION) {
MachO::source_version_command Sd = Obj->getSourceVersionCommand(Command);
PrintSourceVersionCommand(Sd);