mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-27 06:54:30 +00:00
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
5efa0b5fb4
commit
59a3f7063b
@ -351,6 +351,8 @@ public:
|
||||
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
|
||||
|
@ -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_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
|
||||
|
||||
@ -109,6 +110,7 @@ LOAD_COMMAND_STRUCT(thread_command)
|
||||
LOAD_COMMAND_STRUCT(twolevel_hints_command)
|
||||
LOAD_COMMAND_STRUCT(uuid_command)
|
||||
LOAD_COMMAND_STRUCT(version_min_command)
|
||||
LOAD_COMMAND_STRUCT(note_command)
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -819,6 +819,14 @@ namespace llvm {
|
||||
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;
|
||||
@ -1266,6 +1274,13 @@ namespace llvm {
|
||||
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);
|
||||
|
@ -784,6 +784,31 @@ static Error checkVersCommand(const MachOObjectFile &Obj,
|
||||
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) {
|
||||
@ -1280,6 +1305,9 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
|
||||
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;
|
||||
@ -3289,6 +3317,11 @@ MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
|
||||
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);
|
||||
|
@ -558,6 +558,14 @@ void MappingTraits<MachO::version_min_command>::mapping(
|
||||
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
|
||||
|
BIN
test/Object/Inputs/macho-invalid-note
Normal file
BIN
test/Object/Inputs/macho-invalid-note
Normal file
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
|
||||
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)
|
||||
|
50
test/ObjectYAML/MachO/note_command.yaml
Normal file
50
test/ObjectYAML/MachO/note_command.yaml
Normal 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
|
BIN
test/tools/llvm-objdump/X86/Inputs/note.macho-x86
Normal file
BIN
test/tools/llvm-objdump/X86/Inputs/note.macho-x86
Normal file
Binary file not shown.
@ -23,6 +23,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
|
||||
@ -544,3 +546,9 @@ CODESIG: cmd LC_CODE_SIGNATURE
|
||||
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
|
||||
|
@ -8169,6 +8169,19 @@ static void PrintVersionMinLoadCommand(MachO::version_min_command vd) {
|
||||
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;
|
||||
@ -9014,6 +9027,9 @@ static void PrintLoadCommands(const MachOObjectFile *Obj, uint32_t filetype,
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user