1 //===- InputFiles.h ---------------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLD_MACHO_INPUT_FILES_H
10 #define LLD_MACHO_INPUT_FILES_H
12 #include "MachOStructs.h"
14 #include "lld/Common/LLVM.h"
15 #include "lld/Common/Memory.h"
16 #include "llvm/ADT/DenseSet.h"
17 #include "llvm/BinaryFormat/MachO.h"
18 #include "llvm/Object/Archive.h"
19 #include "llvm/Support/MemoryBuffer.h"
20 #include "llvm/TextAPI/MachO/InterfaceFile.h"
21 #include "llvm/TextAPI/MachO/TextAPIReader.h"
33 // If .subsections_via_symbols is set, each InputSection will be split along
34 // symbol boundaries. The keys of a SubsectionMap represent the offsets of
35 // each subsection from the start of the original pre-split InputSection.
36 using SubsectionMap
= std::map
<uint32_t, InputSection
*>;
47 virtual ~InputFile() = default;
48 Kind
kind() const { return fileKind
; }
49 StringRef
getName() const { return name
; }
52 std::vector
<Symbol
*> symbols
;
53 ArrayRef
<llvm::MachO::section_64
> sectionHeaders
;
54 std::vector
<SubsectionMap
> subsections
;
57 InputFile(Kind kind
, MemoryBufferRef mb
)
58 : mb(mb
), fileKind(kind
), name(mb
.getBufferIdentifier()) {}
60 InputFile(Kind kind
, const llvm::MachO::InterfaceFile
&interface
)
61 : fileKind(kind
), name(saver
.save(interface
.getPath())) {}
63 void parseSections(ArrayRef
<llvm::MachO::section_64
>);
65 void parseSymbols(ArrayRef
<lld::structs::nlist_64
> nList
, const char *strtab
,
66 bool subsectionsViaSymbols
);
68 Symbol
*parseNonSectionSymbol(const structs::nlist_64
&sym
, StringRef name
);
70 void parseRelocations(const llvm::MachO::section_64
&, SubsectionMap
&);
78 class ObjFile
: public InputFile
{
80 explicit ObjFile(MemoryBufferRef mb
);
81 static bool classof(const InputFile
*f
) { return f
->kind() == ObjKind
; }
84 // command-line -sectcreate file
85 class OpaqueFile
: public InputFile
{
87 explicit OpaqueFile(MemoryBufferRef mb
, StringRef segName
,
89 static bool classof(const InputFile
*f
) { return f
->kind() == OpaqueKind
; }
93 class DylibFile
: public InputFile
{
95 // Mach-O dylibs can re-export other dylibs as sub-libraries, meaning that the
96 // symbols in those sub-libraries will be available under the umbrella
97 // library's namespace. Those sub-libraries can also have their own
98 // re-exports. When loading a re-exported dylib, `umbrella` should be set to
99 // the root dylib to ensure symbols in the child library are correctly bound
100 // to the root. On the other hand, if a dylib is being directly loaded
101 // (through an -lfoo flag), then `umbrella` should be a nullptr.
102 explicit DylibFile(MemoryBufferRef mb
, DylibFile
*umbrella
= nullptr);
104 explicit DylibFile(const llvm::MachO::InterfaceFile
&interface
,
105 DylibFile
*umbrella
= nullptr);
107 static bool classof(const InputFile
*f
) { return f
->kind() == DylibKind
; }
110 uint64_t ordinal
= 0; // Ordinal numbering starts from 1, so 0 is a sentinel
111 bool reexport
= false;
112 bool forceWeakImport
= false;
113 std::vector
<DylibFile
*> reexported
;
117 class ArchiveFile
: public InputFile
{
119 explicit ArchiveFile(std::unique_ptr
<llvm::object::Archive
> &&file
);
120 static bool classof(const InputFile
*f
) { return f
->kind() == ArchiveKind
; }
121 void fetch(const llvm::object::Archive::Symbol
&sym
);
124 std::unique_ptr
<llvm::object::Archive
> file
;
125 // Keep track of children fetched from the archive by tracking
126 // which address offsets have been fetched already.
127 llvm::DenseSet
<uint64_t> seen
;
130 extern std::vector
<InputFile
*> inputFiles
;
132 llvm::Optional
<MemoryBufferRef
> readFile(StringRef path
);
134 const llvm::MachO::load_command
*
135 findCommand(const llvm::MachO::mach_header_64
*, uint32_t type
);
139 std::string
toString(const macho::InputFile
*file
);