llvm.org GIT mirror llvm / a94c339
[MC/Mach-O] Add support for linker options in Mach-O files. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172779 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Dunbar 7 years ago
9 changed file(s) with 149 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
848848 std::vector IndirectSymbols;
849849
850850 std::vector DataRegions;
851
852 /// The list of linker options to propagate into the object file.
853 std::vector > LinkerOptions;
854
851855 /// The set of function symbols for which a .thumb_func directive has
852856 /// been seen.
853857 //
10591063 size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
10601064
10611065 /// @}
1066 /// @name Linker Option List Access
1067 /// @{
1068
1069 std::vector > &getLinkerOptions() {
1070 return LinkerOptions;
1071 }
1072
1073 /// @}
10621074 /// @name Data Region List Access
10631075 /// @{
10641076
194194
195195 void WriteLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset,
196196 uint32_t DataSize);
197
198 void WriteLinkerOptionsLoadCommand(const std::vector &Options);
197199
198200 // FIXME: We really need to improve the relocation validation. Basically, we
199201 // want to implement a separate computation which evaluates the relocation
147147 LCT_CodeSignature = 0x1d,
148148 LCT_SegmentSplitInfo = 0x1e,
149149 LCT_FunctionStarts = 0x26,
150 LCT_DataInCode = 0x29
150 LCT_DataInCode = 0x29,
151 LCT_LinkerOptions = 0x2D
151152 };
152153
153154 /// \brief Load command structure.
233234 uint32_t Size;
234235 uint32_t DataOffset;
235236 uint32_t DataSize;
237 };
238
239 struct LinkerOptionsLoadCommand {
240 uint32_t Type;
241 uint32_t Size;
242 uint32_t Count;
243 // Load command is followed by Count number of zero-terminated UTF8 strings,
244 // and then zero-filled to be 4-byte aligned.
236245 };
237246
238247 /// @}
152152 void ReadLinkeditDataLoadCommand(
153153 const LoadCommandInfo &LCI,
154154 InMemoryStruct &Res) const;
155 void ReadLinkerOptionsLoadCommand(
156 const LoadCommandInfo &LCI,
157 InMemoryStruct &Res) const;
155158 void ReadIndirectSymbolTableEntry(
156159 const macho::DysymtabLoadCommand &DLC,
157160 unsigned Index,
4747 virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
4848 MCSymbol *EHSymbol);
4949 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
50 virtual void EmitLinkerOptions(ArrayRef Options);
5051 virtual void EmitDataRegion(MCDataRegionType Kind);
5152 virtual void EmitThumbFunc(MCSymbol *Func);
5253 virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
175176 getAssembler().setSubsectionsViaSymbols(true);
176177 return;
177178 }
179 }
180
181 void MCMachOStreamer::EmitLinkerOptions(ArrayRef Options) {
182 getAssembler().getLinkerOptions().push_back(Options);
178183 }
179184
180185 void MCMachOStreamer::EmitDataRegion(MCDataRegionType Kind) {
373373 Write32(DataSize);
374374
375375 assert(OS.tell() - Start == macho::LinkeditLoadCommandSize);
376 }
377
378 static unsigned ComputeLinkerOptionsLoadCommandSize(
379 const std::vector &Options)
380 {
381 unsigned Size = sizeof(macho::LinkerOptionsLoadCommand);
382 for (unsigned i = 0, e = Options.size(); i != e; ++i)
383 Size += Options[i].size() + 1;
384 return RoundUpToAlignment(Size, 4);
385 }
386
387 void MachObjectWriter::WriteLinkerOptionsLoadCommand(
388 const std::vector &Options)
389 {
390 unsigned Size = ComputeLinkerOptionsLoadCommandSize(Options);
391 uint64_t Start = OS.tell();
392 (void) Start;
393
394 Write32(macho::LCT_LinkerOptions);
395 Write32(Size);
396 Write32(Options.size());
397 uint64_t BytesWritten = 0;
398 for (unsigned i = 0, e = Options.size(); i != e; ++i) {
399 // Write each string, including the null byte.
400 const std::string &Option = Options[i];
401 WriteBytes(Option.c_str(), Option.size() + 1);
402 BytesWritten += Option.size() + 1;
403 }
404
405 // Pad to a multiple of 4.
406 WriteBytes("", OffsetToAlignment(BytesWritten, 4));
407
408 assert(OS.tell() - Start == Size);
376409 }
377410
378411
692725 macho::SegmentLoadCommand64Size + NumSections * macho::Section64Size :
693726 macho::SegmentLoadCommand32Size + NumSections * macho::Section32Size;
694727
728 // Add the data-in-code load command size, if used.
729 unsigned NumDataRegions = Asm.getDataRegions().size();
730 if (NumDataRegions) {
731 ++NumLoadCommands;
732 LoadCommandsSize += macho::LinkeditLoadCommandSize;
733 }
734
695735 // Add the symbol table load command sizes, if used.
696736 unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +
697737 UndefinedSymbolData.size();
701741 macho::DysymtabLoadCommandSize);
702742 }
703743
704 // Add the data-in-code load command size, if used.
705 unsigned NumDataRegions = Asm.getDataRegions().size();
706 if (NumDataRegions) {
744 // Add the linker option load commands sizes.
745 const std::vector > &LinkerOptions =
746 Asm.getLinkerOptions();
747 for (unsigned i = 0, e = LinkerOptions.size(); i != e; ++i) {
707748 ++NumLoadCommands;
708 LoadCommandsSize += macho::LinkeditLoadCommandSize;
709 }
710
749 LoadCommandsSize += ComputeLinkerOptionsLoadCommandSize(LinkerOptions[i]);
750 }
751
711752 // Compute the total size of the section data, as well as its file size and vm
712753 // size.
713754 uint64_t SectionDataStart = (is64Bit() ? macho::Header64Size :
796837 FirstExternalSymbol, NumExternalSymbols,
797838 FirstUndefinedSymbol, NumUndefinedSymbols,
798839 IndirectSymbolOffset, NumIndirectSymbols);
840 }
841
842 // Write the linker options load commands.
843 for (unsigned i = 0, e = LinkerOptions.size(); i != e; ++i) {
844 WriteLinkerOptionsLoadCommand(LinkerOptions[i]);
799845 }
800846
801847 // Write the actual section data.
258258 }
259259
260260 template<>
261 void SwapStruct(macho::LinkerOptionsLoadCommand &Value) {
262 SwapValue(Value.Type);
263 SwapValue(Value.Size);
264 SwapValue(Value.Count);
265 }
266 void MachOObject::ReadLinkerOptionsLoadCommand(const LoadCommandInfo &LCI,
267 InMemoryStruct &Res) const {
268 ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
269 }
270
271 template<>
261272 void SwapStruct(macho::IndirectSymbolTableEntry &Value) {
262273 SwapValue(Value.Index);
263274 }
0 // RUN: llvm-mc -n -triple x86_64-apple-darwin10 %s -filetype=obj | macho-dump | FileCheck %s
1
2 // CHECK: ('load_commands_size', 104)
3 // CHECK: ('load_commands', [
4 // CHECK: # Load Command 1
5 // CHECK: (('command', 45)
6 // CHECK: ('size', 16)
7 // CHECK: ('count', 1)
8 // CHECK: ('_strings', [
9 // CHECK: "a",
10 // CHECK: ])
11 // CHECK: ),
12 // CHECK: # Load Command 2
13 // CHECK: (('command', 45)
14 // CHECK: ('size', 16)
15 // CHECK: ('count', 2)
16 // CHECK: ('_strings', [
17 // CHECK: "a",
18 // CHECK: "b",
19 // CHECK: ])
20 // CHECK: ),
21 // CHECK: ])
22
23 .linker_option "a"
24 .linker_option "a", "b"
336336 InMemoryStruct LLC;
337337 Obj.ReadLinkeditDataLoadCommand(LCI, LLC);
338338 if (!LLC)
339 return Error("unable to read segment load command");
339 return Error("unable to read data-in-code load command");
340340
341341 outs() << " ('dataoff', " << LLC->DataOffset << ")\n"
342342 << " ('datasize', " << LLC->DataSize << ")\n"
360360 return 0;
361361 }
362362
363 static int DumpLinkerOptionsCommand(MachOObject &Obj,
364 const MachOObject::LoadCommandInfo &LCI) {
365 InMemoryStruct LOLC;
366 Obj.ReadLinkerOptionsLoadCommand(LCI, LOLC);
367 if (!LOLC)
368 return Error("unable to read linker options load command");
369
370 outs() << " ('count', " << LOLC->Count << ")\n"
371 << " ('_strings', [\n";
372
373 uint64_t DataSize = LOLC->Size - sizeof(macho::LinkerOptionsLoadCommand);
374 StringRef Data = Obj.getData(
375 LCI.Offset + sizeof(macho::LinkerOptionsLoadCommand), DataSize);
376 for (unsigned i = 0; i != LOLC->Count; ++i) {
377 std::pair Split = Data.split('\0');
378 outs() << "\t\"";
379 outs().write_escaped(Split.first);
380 outs() << "\",\n";
381 Data = Split.second;
382 }
383 outs() <<" ])\n";
384
385 return 0;
386 }
387
363388
364389 static int DumpLoadCommand(MachOObject &Obj, unsigned Index) {
365390 const MachOObject::LoadCommandInfo &LCI = Obj.getLoadCommandInfo(Index);
389414 case macho::LCT_DataInCode:
390415 Res = DumpDataInCodeDataCommand(Obj, LCI);
391416 break;
417 case macho::LCT_LinkerOptions:
418 Res = DumpLinkerOptionsCommand(Obj, LCI);
419 break;
392420 default:
393421 Warning("unknown load command: " + Twine(LCI.Command.Type));
394422 break;