forked from OSchip/llvm-project
Add support for the new LC_NOTE load command.
It describes a region of arbitrary data included in a Mach-O file. Its initial use is to record extra data in MH_CORE files. rdar://30001545 rdar://30001731 llvm-svn: 292500
This commit is contained in:
parent
4687db0e09
commit
a4579c4184
|
@ -351,6 +351,8 @@ public:
|
||||||
getLinkerOptionLoadCommand(const LoadCommandInfo &L) const;
|
getLinkerOptionLoadCommand(const LoadCommandInfo &L) const;
|
||||||
MachO::version_min_command
|
MachO::version_min_command
|
||||||
getVersionMinLoadCommand(const LoadCommandInfo &L) const;
|
getVersionMinLoadCommand(const LoadCommandInfo &L) const;
|
||||||
|
MachO::note_command
|
||||||
|
getNoteLoadCommand(const LoadCommandInfo &L) const;
|
||||||
MachO::dylib_command
|
MachO::dylib_command
|
||||||
getDylibIDLoadCommand(const LoadCommandInfo &L) const;
|
getDylibIDLoadCommand(const LoadCommandInfo &L) const;
|
||||||
MachO::dyld_info_command
|
MachO::dyld_info_command
|
||||||
|
|
|
@ -73,6 +73,7 @@ HANDLE_LOAD_COMMAND(LC_LINKER_OPTION, 0x0000002Du, linker_option_command)
|
||||||
HANDLE_LOAD_COMMAND(LC_LINKER_OPTIMIZATION_HINT, 0x0000002Eu, linkedit_data_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_TVOS, 0x0000002Fu, version_min_command)
|
||||||
HANDLE_LOAD_COMMAND(LC_VERSION_MIN_WATCHOS, 0x00000030u, version_min_command)
|
HANDLE_LOAD_COMMAND(LC_VERSION_MIN_WATCHOS, 0x00000030u, version_min_command)
|
||||||
|
HANDLE_LOAD_COMMAND(LC_NOTE, 0x00000031u, note_command)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -109,6 +110,7 @@ LOAD_COMMAND_STRUCT(thread_command)
|
||||||
LOAD_COMMAND_STRUCT(twolevel_hints_command)
|
LOAD_COMMAND_STRUCT(twolevel_hints_command)
|
||||||
LOAD_COMMAND_STRUCT(uuid_command)
|
LOAD_COMMAND_STRUCT(uuid_command)
|
||||||
LOAD_COMMAND_STRUCT(version_min_command)
|
LOAD_COMMAND_STRUCT(version_min_command)
|
||||||
|
LOAD_COMMAND_STRUCT(note_command)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -819,6 +819,14 @@ namespace llvm {
|
||||||
uint32_t sdk; // X.Y.Z is encoded in nibbles xxxx.yy.zz
|
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 {
|
struct dyld_info_command {
|
||||||
uint32_t cmd;
|
uint32_t cmd;
|
||||||
uint32_t cmdsize;
|
uint32_t cmdsize;
|
||||||
|
@ -1266,6 +1274,13 @@ namespace llvm {
|
||||||
sys::swapByteOrder(C.sdk);
|
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) {
|
inline void swapStruct(data_in_code_entry &C) {
|
||||||
sys::swapByteOrder(C.offset);
|
sys::swapByteOrder(C.offset);
|
||||||
sys::swapByteOrder(C.length);
|
sys::swapByteOrder(C.length);
|
||||||
|
|
|
@ -784,6 +784,31 @@ static Error checkVersCommand(const MachOObjectFile &Obj,
|
||||||
return Error::success();
|
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,
|
static Error checkRpathCommand(const MachOObjectFile &Obj,
|
||||||
const MachOObjectFile::LoadCommandInfo &Load,
|
const MachOObjectFile::LoadCommandInfo &Load,
|
||||||
uint32_t LoadCommandIndex) {
|
uint32_t LoadCommandIndex) {
|
||||||
|
@ -1280,6 +1305,9 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
|
||||||
if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
|
if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd,
|
||||||
"LC_VERSION_MIN_WATCHOS")))
|
"LC_VERSION_MIN_WATCHOS")))
|
||||||
return;
|
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) {
|
} else if (Load.C.cmd == MachO::LC_RPATH) {
|
||||||
if ((Err = checkRpathCommand(*this, Load, I)))
|
if ((Err = checkRpathCommand(*this, Load, I)))
|
||||||
return;
|
return;
|
||||||
|
@ -3289,6 +3317,11 @@ MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
|
||||||
return getStruct<MachO::version_min_command>(*this, L.Ptr);
|
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
|
MachO::dylib_command
|
||||||
MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
|
MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
|
||||||
return getStruct<MachO::dylib_command>(*this, L.Ptr);
|
return getStruct<MachO::dylib_command>(*this, L.Ptr);
|
||||||
|
|
|
@ -558,6 +558,14 @@ void MappingTraits<MachO::version_min_command>::mapping(
|
||||||
IO.mapRequired("sdk", LoadCommand.sdk);
|
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::yaml
|
||||||
|
|
||||||
} // namespace llvm
|
} // namespace llvm
|
||||||
|
|
Binary file not shown.
|
@ -505,3 +505,6 @@ INVALID-FAT-ARCH-OVERLAP: macho-invalid-fat-arch-overlap': truncated or malforme
|
||||||
|
|
||||||
RUN: not llvm-objdump -macho -universal-headers %p/Inputs/macho-invalid-fat-arch-overlapheaders 2>&1 | FileCheck -check-prefix INVALID-FAT-ARCH-OVERLAPHEADERS %s
|
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)
|
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)
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
# 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
|
Binary file not shown.
|
@ -23,6 +23,8 @@
|
||||||
// RUN: | FileCheck %s -check-prefix=NON_VERBOSE
|
// RUN: | FileCheck %s -check-prefix=NON_VERBOSE
|
||||||
// RUN: llvm-objdump -p %p/Inputs/codesig.macho-x86_64 \
|
// RUN: llvm-objdump -p %p/Inputs/codesig.macho-x86_64 \
|
||||||
// RUN: | FileCheck %s -check-prefix=CODESIG
|
// 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: Mach header
|
||||||
CHECK: magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
|
CHECK: magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
|
||||||
|
@ -544,3 +546,9 @@ CODESIG: cmd LC_CODE_SIGNATURE
|
||||||
CODESIG: cmdsize 16
|
CODESIG: cmdsize 16
|
||||||
CODESIG: dataoff 8496
|
CODESIG: dataoff 8496
|
||||||
CODESIG: datasize 64
|
CODESIG: datasize 64
|
||||||
|
|
||||||
|
NOTE: cmd LC_NOTE
|
||||||
|
NOTE: cmdsize 40
|
||||||
|
NOTE: data_owner DATA OWNER
|
||||||
|
NOTE: offset 68
|
||||||
|
NOTE: size 8
|
||||||
|
|
|
@ -8169,6 +8169,19 @@ static void PrintVersionMinLoadCommand(MachO::version_min_command vd) {
|
||||||
outs() << "\n";
|
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) {
|
static void PrintSourceVersionCommand(MachO::source_version_command sd) {
|
||||||
outs() << " cmd LC_SOURCE_VERSION\n";
|
outs() << " cmd LC_SOURCE_VERSION\n";
|
||||||
outs() << " cmdsize " << sd.cmdsize;
|
outs() << " cmdsize " << sd.cmdsize;
|
||||||
|
@ -9014,6 +9027,9 @@ static void PrintLoadCommands(const MachOObjectFile *Obj, uint32_t filetype,
|
||||||
Command.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
|
Command.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
|
||||||
MachO::version_min_command Vd = Obj->getVersionMinLoadCommand(Command);
|
MachO::version_min_command Vd = Obj->getVersionMinLoadCommand(Command);
|
||||||
PrintVersionMinLoadCommand(Vd);
|
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) {
|
} else if (Command.C.cmd == MachO::LC_SOURCE_VERSION) {
|
||||||
MachO::source_version_command Sd = Obj->getSourceVersionCommand(Command);
|
MachO::source_version_command Sd = Obj->getSourceVersionCommand(Command);
|
||||||
PrintSourceVersionCommand(Sd);
|
PrintSourceVersionCommand(Sd);
|
||||||
|
|
Loading…
Reference in New Issue