LLVM  9.0.0svn
XCOFFObjectFile.cpp
Go to the documentation of this file.
1 //===--- XCOFFObjectFile.cpp - XCOFF object file implementation -----------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the XCOFFObjectFile class.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/Support/Endian.h"
19 #include <cstddef>
20 #include <cstring>
21 
22 namespace llvm {
23 namespace object {
24 
25 enum { XCOFF32FileHeaderSize = 20 };
26 static_assert(sizeof(XCOFFFileHeader) == XCOFF32FileHeaderSize,
27  "Wrong size for XCOFF file header.");
28 
29 // Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
30 // Returns unexpected_eof on error.
31 template <typename T>
32 static std::error_code getObject(const T *&Obj, MemoryBufferRef M,
33  const void *Ptr,
34  const uint64_t Size = sizeof(T)) {
35  uintptr_t Addr = uintptr_t(Ptr);
36  if (std::error_code EC = Binary::checkOffset(M, Addr, Size))
37  return EC;
38  Obj = reinterpret_cast<const T *>(Addr);
39  return std::error_code();
40 }
41 
42 template <typename T> static const T *viewAs(uintptr_t in) {
43  return reinterpret_cast<const T *>(in);
44 }
45 
46 const XCOFFSectionHeader *XCOFFObjectFile::toSection(DataRefImpl Ref) const {
47  auto Sec = viewAs<XCOFFSectionHeader>(Ref.p);
48 #ifndef NDEBUG
49  if (Sec < SectionHdrTablePtr ||
50  Sec >= (SectionHdrTablePtr + getNumberOfSections()))
51  report_fatal_error("Section header outside of section header table.");
52 
53  uintptr_t Offset = uintptr_t(Sec) - uintptr_t(SectionHdrTablePtr);
54  if (Offset % getSectionHeaderSize() != 0)
56  "Section header pointer does not point to a valid section header.");
57 #endif
58  return Sec;
59 }
60 
61 // The next 2 functions are not exactly necessary yet, but they are useful to
62 // abstract over the size difference between XCOFF32 and XCOFF64 structure
63 // definitions.
64 size_t XCOFFObjectFile::getFileHeaderSize() const {
65  return sizeof(XCOFFFileHeader);
66 }
67 
68 size_t XCOFFObjectFile::getSectionHeaderSize() const {
69  return sizeof(XCOFFSectionHeader);
70 }
71 
73  llvm_unreachable("Not yet implemented!");
74  return;
75 }
76 
78  StringRef Result;
79  llvm_unreachable("Not yet implemented!");
80  return Result;
81 }
82 
84  uint64_t Result = 0;
85  llvm_unreachable("Not yet implemented!");
86  return Result;
87 }
88 
90  uint64_t Result = 0;
91  llvm_unreachable("Not yet implemented!");
92  return Result;
93 }
94 
96  uint64_t Result = 0;
97  llvm_unreachable("Not yet implemented!");
98  return Result;
99 }
100 
103  llvm_unreachable("Not yet implemented!");
104  return SymbolRef::ST_Other;
105 }
106 
109  llvm_unreachable("Not yet implemented!");
110  return section_iterator(SectionRef());
111 }
112 
114  const char *Ptr = reinterpret_cast<const char *>(Sec.p);
115  Sec.p = reinterpret_cast<uintptr_t>(Ptr + getSectionHeaderSize());
116 }
117 
119  const char *Name = toSection(Sec)->Name;
120  auto NulCharPtr =
121  static_cast<const char *>(memchr(Name, '\0', XCOFF::SectionNameSize));
122  return NulCharPtr ? StringRef(Name, NulCharPtr - Name)
123  : StringRef(Name, XCOFF::SectionNameSize);
124 }
125 
127  return toSection(Sec)->VirtualAddress;
128 }
129 
131  // Section numbers in XCOFF are numbered beginning at 1. A section number of
132  // zero is used to indicate that a symbol is being imported or is undefined.
133  return toSection(Sec) - SectionHdrTablePtr + 1;
134 }
135 
137  return toSection(Sec)->SectionSize;
138 }
139 
142  llvm_unreachable("Not yet implemented!");
143 }
144 
146  uint64_t Result = 0;
147  llvm_unreachable("Not yet implemented!");
148  return Result;
149 }
150 
152  bool Result = false;
153  llvm_unreachable("Not yet implemented!");
154  return Result;
155 }
156 
158  return toSection(Sec)->Flags & XCOFF::STYP_TEXT;
159 }
160 
162  unsigned Flags = toSection(Sec)->Flags;
163  return Flags & (XCOFF::STYP_DATA | XCOFF::STYP_TDATA);
164 }
165 
167  unsigned Flags = toSection(Sec)->Flags;
168  return Flags & (XCOFF::STYP_BSS | XCOFF::STYP_TBSS);
169 }
170 
172  bool Result = false;
173  llvm_unreachable("Not yet implemented!");
174  return Result;
175 }
176 
178  llvm_unreachable("Not yet implemented!");
180 }
181 
183  llvm_unreachable("Not yet implemented!");
185 }
186 
188  llvm_unreachable("Not yet implemented!");
189  return;
190 }
191 
193  llvm_unreachable("Not yet implemented!");
194  uint64_t Result = 0;
195  return Result;
196 }
197 
199  llvm_unreachable("Not yet implemented!");
200  return symbol_iterator(SymbolRef());
201 }
202 
204  llvm_unreachable("Not yet implemented!");
205  uint64_t Result = 0;
206  return Result;
207 }
208 
210  DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
211  llvm_unreachable("Not yet implemented!");
212  return;
213 }
214 
216  uint32_t Result = 0;
217  llvm_unreachable("Not yet implemented!");
218  return Result;
219 }
220 
222  llvm_unreachable("Not yet implemented!");
224 }
225 
227  llvm_unreachable("Not yet implemented!");
229 }
230 
232  DataRefImpl DRI;
233  DRI.p = reinterpret_cast<uintptr_t>(SectionHdrTablePtr);
234  return section_iterator(SectionRef(DRI, this));
235 }
236 
238  DataRefImpl DRI;
239  DRI.p =
240  reinterpret_cast<uintptr_t>(SectionHdrTablePtr + getNumberOfSections());
241  return section_iterator(SectionRef(DRI, this));
242 }
243 
245  // Only support 32-bit object files for now ...
246  assert(getFileHeaderSize() == XCOFF32FileHeaderSize);
247  return 4;
248 }
249 
251  assert(getFileHeaderSize() == XCOFF32FileHeaderSize);
252  return "aixcoff-rs6000";
253 }
254 
256  assert(getFileHeaderSize() == XCOFF32FileHeaderSize);
257  return Triple::ppc;
258 }
259 
261  llvm_unreachable("Not yet implemented!");
262  return SubtargetFeatures();
263 }
264 
266  bool Result = false;
267  llvm_unreachable("Not yet implemented!");
268  return Result;
269 }
270 
272  // TODO FIXME Should get from auxiliary_header->o_entry when support for the
273  // auxiliary_header is added.
274  return 0;
275 }
276 
278  : ObjectFile(Binary::ID_XCOFF32, Object) {
279 
280  // Current location within the file.
281  uint64_t CurPtr = 0;
282 
283  if ((EC = getObject(FileHdrPtr, Data, base() + CurPtr)))
284  return;
285 
286  CurPtr += getFileHeaderSize();
287  // TODO FIXME we don't have support for an optional header yet, so just skip
288  // past it.
289  CurPtr += FileHdrPtr->AuxHeaderSize;
290 
291  if (getNumberOfSections() != 0) {
292  if ((EC = getObject(SectionHdrTablePtr, Data, base() + CurPtr,
293  getNumberOfSections() * getSectionHeaderSize())))
294  return;
295  }
296 }
297 
298 uint16_t XCOFFObjectFile::getMagic() const {
299  return FileHdrPtr->Magic;
300 }
301 
303  return FileHdrPtr->NumberOfSections;
304 }
305 
307  return FileHdrPtr->TimeStamp;
308 }
309 
311  return FileHdrPtr->SymbolTableOffset;
312 }
313 
315  // As far as symbol table size is concerned, if this field is negative it is
316  // to be treated as a 0. However since this field is also used for printing we
317  // don't want to truncate any negative values.
318  return FileHdrPtr->NumberOfSymTableEntries;
319 }
320 
322  return FileHdrPtr->AuxHeaderSize;
323 }
324 
325 uint16_t XCOFFObjectFile::getFlags() const {
326  return FileHdrPtr->Flags;
327 }
328 
331  StringRef Data = Object.getBuffer();
333  std::error_code EC;
334  std::unique_ptr<ObjectFile> Ret;
335 
336  if (Type == file_magic::xcoff_object_32) {
337  Ret.reset(new XCOFFObjectFile(Object, EC));
338  } else {
339  llvm_unreachable("Encountered an unexpected binary file type!");
340  }
341 
342  if (EC)
343  return errorCodeToError(EC);
344  return std::move(Ret);
345 }
346 
347 } // namespace object
348 } // namespace llvm
void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override
32-bit XCOFF object file
Definition: Magic.h:48
uint64_t getRelocationType(DataRefImpl Rel) const override
bool isSectionData(DataRefImpl Sec) const override
friend class SymbolRef
Definition: ObjectFile.h:244
void moveRelocationNext(DataRefImpl &Rel) const override
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:139
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Expected< section_iterator > getSymbolSection(DataRefImpl Symb) const override
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
friend class SectionRef
Definition: ObjectFile.h:258
int32_t getNumberOfSymbolTableEntries() const
basic_symbol_iterator symbol_end() const override
static std::error_code checkOffset(MemoryBufferRef M, uintptr_t Addr, const uint64_t Size)
Definition: Binary.h:155
This class is the base class for all object file types.
Definition: ObjectFile.h:226
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override
static std::error_code getObject(const T *&Obj, MemoryBufferRef M, const void *Ptr, const uint64_t Size=sizeof(T))
const uint8_t * base() const
Definition: ObjectFile.h:232
Expected< uint64_t > getStartAddress() const override
Expected< ArrayRef< uint8_t > > getSectionContents(DataRefImpl Sec) const override
uint32_t getSymbolFlags(DataRefImpl Symb) const override
void moveSectionNext(DataRefImpl &Sec) const override
relocation_iterator section_rel_end(DataRefImpl Sec) const override
StringRef getBuffer() const
Definition: MemoryBuffer.h:272
Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override
file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
Definition: Magic.cpp:34
The access may reference the value stored in memory.
XCOFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
uint64_t getRelocationOffset(DataRefImpl Rel) const override
Tagged union holding either a T or a Error.
Definition: CachePruning.h:22
section_iterator section_begin() const override
content_iterator< SectionRef > section_iterator
Definition: ObjectFile.h:48
uint16_t getOptionalHeaderSize() const
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
SubtargetFeatures getFeatures() const override
uint64_t getSectionAlignment(DataRefImpl Sec) const override
void moveSymbolNext(DataRefImpl &Symb) const override
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
uint64_t getSectionAddress(DataRefImpl Sec) const override
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:87
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override
bool isSectionText(DataRefImpl Sec) const override
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
Triple::ArchType getArch() const override
basic_symbol_iterator symbol_begin() const override
static Expected< std::unique_ptr< ObjectFile > > createXCOFFObjectFile(MemoryBufferRef Object)
static const T * viewAs(uintptr_t in)
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint64_t getSectionSize(DataRefImpl Sec) const override
support::ubig16_t AuxHeaderSize
uint8_t getBytesInAddress() const override
The number of bytes used to represent an address in this object file format.
section_iterator section_end() const override
friend class RelocationRef
Definition: ObjectFile.h:283
bool isSectionCompressed(DataRefImpl Sec) const override
bool isSectionBSS(DataRefImpl Sec) const override
support::big32_t NumberOfSymTableEntries
content_iterator< BasicSymbolRef > basic_symbol_iterator
Definition: SymbolicFile.h:138
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
MemoryBufferRef Data
Definition: Binary.h:37
Manages the enabling and disabling of subtarget specific features.
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override
Expected< StringRef > getSectionName(DataRefImpl Sec) const override
support::ubig16_t NumberOfSections
uint32_t Size
Definition: Profile.cpp:46
uint64_t getSectionIndex(DataRefImpl Sec) const override
support::ubig32_t SymbolTableOffset
char Name[XCOFF::SectionNameSize]
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef getFileFormatName() const override
content_iterator< RelocationRef > relocation_iterator
Definition: ObjectFile.h:77
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
bool isSectionVirtual(DataRefImpl Sec) const override
file_magic - An "enum class" enumeration of file types based on magic (the first N bytes of the file)...
Definition: Magic.h:20