[llvm] r359244 - [Object][XCOFF] Add intial support for section header table.
Sean Fertile via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 25 14:36:04 PDT 2019
Author: sfertile
Date: Thu Apr 25 14:36:04 2019
New Revision: 359244
URL: http://llvm.org/viewvc/llvm-project?rev=359244&view=rev
Log:
[Object][XCOFF] Add intial support for section header table.
Adds a representation of the section header table to XCOFFObjectFile,
and implements enough to dump the section headers with llvm-obdump.
Differential Revision: https://reviews.llvm.org/D60784
Added:
llvm/trunk/include/llvm/BinaryFormat/XCOFF.h
llvm/trunk/test/tools/llvm-objdump/Inputs/xcoff-long-sec-names.o (with props)
llvm/trunk/test/tools/llvm-objdump/Inputs/xcoff-section-headers-truncate.o (with props)
llvm/trunk/test/tools/llvm-objdump/Inputs/xcoff-section-headers.o (with props)
llvm/trunk/test/tools/llvm-objdump/xcoff-section-headers.test
Modified:
llvm/trunk/include/llvm/Object/XCOFFObjectFile.h
llvm/trunk/lib/Object/XCOFFObjectFile.cpp
Added: llvm/trunk/include/llvm/BinaryFormat/XCOFF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/XCOFF.h?rev=359244&view=auto
==============================================================================
--- llvm/trunk/include/llvm/BinaryFormat/XCOFF.h (added)
+++ llvm/trunk/include/llvm/BinaryFormat/XCOFF.h Thu Apr 25 14:36:04 2019
@@ -0,0 +1,43 @@
+//===-- llvm/BinaryFormat/XCOFF.h - The XCOFF file format -------*- C++/-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines manifest constants for the XCOFF object file format.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BINARYFORMAT_XCOFF_H
+#define LLVM_BINARYFORMAT_XCOFF_H
+
+namespace llvm {
+namespace XCOFF {
+
+// Constants used in the XCOFF definition.
+enum { SectionNameSize = 8 };
+
+// Flags for defining the section type. Used for the s_flags field of
+// the section header structure. Defined in the system header `scnhdr.h`.
+enum SectionTypeFlags {
+ STYP_PAD = 0x0008,
+ STYP_DWARF = 0x0010,
+ STYP_TEXT = 0x0020,
+ STYP_DATA = 0x0040,
+ STYP_BSS = 0x0080,
+ STYP_EXCEPT = 0x0100,
+ STYP_INFO = 0x0200,
+ STYP_TDATA = 0x0400,
+ STYP_TBSS = 0x0800,
+ STYP_LOADER = 0x1000,
+ STYP_DEBUG = 0x2000,
+ STYP_TYPCHK = 0x4000,
+ STYP_OVRFLO = 0x8000
+};
+
+} // end namespace XCOFF
+} // end namespace llvm
+
+#endif
Modified: llvm/trunk/include/llvm/Object/XCOFFObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/XCOFFObjectFile.h?rev=359244&r1=359243&r2=359244&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/XCOFFObjectFile.h (original)
+++ llvm/trunk/include/llvm/Object/XCOFFObjectFile.h Thu Apr 25 14:36:04 2019
@@ -16,6 +16,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/BinaryFormat/Magic.h"
+#include "llvm/BinaryFormat/XCOFF.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/Error.h"
@@ -47,9 +48,30 @@ struct XCOFFFileHeader {
support::ubig16_t Flags;
};
+struct XCOFFSectionHeader {
+ char Name[XCOFF::SectionNameSize];
+ support::ubig32_t PhysicalAddress;
+ support::ubig32_t VirtualAddress;
+ support::ubig32_t SectionSize;
+ support::ubig32_t FileOffsetToRawData;
+ support::ubig32_t FileOffsetToRelocationInfo;
+ support::ubig32_t FileOffsetToLineNumberInfo;
+ support::ubig16_t NumberOfRelocations;
+ support::ubig16_t NumberOfLineNumbers;
+ support::big32_t Flags;
+};
+
class XCOFFObjectFile : public ObjectFile {
private:
const XCOFFFileHeader *FileHdrPtr = nullptr;
+ const XCOFFSectionHeader *SectionHdrTablePtr = nullptr;
+
+ size_t getFileHeaderSize() const;
+ size_t getSectionHeaderSize() const;
+
+ const XCOFFSectionHeader *toSection(DataRefImpl Ref) const;
+
+ uint16_t getNumberOfSections() const;
public:
void moveSymbolNext(DataRefImpl &Symb) const override;
@@ -95,13 +117,12 @@ public:
StringRef getFileFormatName() const override;
Triple::ArchType getArch() const override;
SubtargetFeatures getFeatures() const override;
+ Expected<uint64_t> getStartAddress() const override;
bool isRelocatableObject() const override;
-public:
XCOFFObjectFile(MemoryBufferRef Object, std::error_code &EC);
const XCOFFFileHeader *getFileHeader() const { return FileHdrPtr; }
-
}; // XCOFFObjectFile
} // namespace object
Modified: llvm/trunk/lib/Object/XCOFFObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/XCOFFObjectFile.cpp?rev=359244&r1=359243&r2=359244&view=diff
==============================================================================
--- llvm/trunk/lib/Object/XCOFFObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/XCOFFObjectFile.cpp Thu Apr 25 14:36:04 2019
@@ -22,6 +22,10 @@
namespace llvm {
namespace object {
+enum { XCOFF32FileHeaderSize = 20 };
+static_assert(sizeof(XCOFFFileHeader) == XCOFF32FileHeaderSize,
+ "Wrong size for XCOFF file header.");
+
// Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
// Returns unexpected_eof on error.
template <typename T>
@@ -35,6 +39,40 @@ static std::error_code getObject(const T
return std::error_code();
}
+template <typename T> static const T *viewAs(uintptr_t in) {
+ return reinterpret_cast<const T *>(in);
+}
+
+const XCOFFSectionHeader *XCOFFObjectFile::toSection(DataRefImpl Ref) const {
+ auto Sec = viewAs<XCOFFSectionHeader>(Ref.p);
+#ifndef NDEBUG
+ if (Sec < SectionHdrTablePtr ||
+ Sec >= (SectionHdrTablePtr + getNumberOfSections()))
+ report_fatal_error("Section header outside of section header table.");
+
+ uintptr_t Offset = uintptr_t(Sec) - uintptr_t(SectionHdrTablePtr);
+ if (Offset % getSectionHeaderSize() != 0)
+ report_fatal_error(
+ "Section header pointer does not point to a valid section header.");
+#endif
+ return Sec;
+}
+
+// The next 2 functions are not exactly necessary yet, but they are useful to
+// abstract over the size difference between XCOFF32 and XCOFF64 structure
+// definitions.
+size_t XCOFFObjectFile::getFileHeaderSize() const {
+ return sizeof(XCOFFFileHeader);
+}
+
+size_t XCOFFObjectFile::getSectionHeaderSize() const {
+ return sizeof(XCOFFSectionHeader);
+}
+
+uint16_t XCOFFObjectFile::getNumberOfSections() const {
+ return FileHdrPtr->NumberOfSections;
+}
+
void XCOFFObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
llvm_unreachable("Not yet implemented!");
return;
@@ -77,32 +115,32 @@ XCOFFObjectFile::getSymbolSection(DataRe
}
void XCOFFObjectFile::moveSectionNext(DataRefImpl &Sec) const {
- llvm_unreachable("Not yet implemented!");
- return;
+ const char *Ptr = reinterpret_cast<const char *>(Sec.p);
+ Sec.p = reinterpret_cast<uintptr_t>(Ptr + getSectionHeaderSize());
}
std::error_code XCOFFObjectFile::getSectionName(DataRefImpl Sec,
StringRef &Res) const {
- llvm_unreachable("Not yet implemented!");
+ const char *Name = toSection(Sec)->Name;
+ auto NulCharPtr =
+ static_cast<const char *>(memchr(Name, '\0', XCOFF::SectionNameSize));
+ Res = NulCharPtr ? StringRef(Name, NulCharPtr - Name)
+ : StringRef(Name, XCOFF::SectionNameSize);
return std::error_code();
}
uint64_t XCOFFObjectFile::getSectionAddress(DataRefImpl Sec) const {
- uint64_t Result = 0;
- llvm_unreachable("Not yet implemented!");
- return Result;
+ return toSection(Sec)->VirtualAddress;
}
uint64_t XCOFFObjectFile::getSectionIndex(DataRefImpl Sec) const {
- uint64_t Result = 0;
- llvm_unreachable("Not yet implemented!");
- return Result;
+ // Section numbers in XCOFF are numbered beginning at 1. A section number of
+ // zero is used to indicate that a symbol is being imported or is undefined.
+ return toSection(Sec) - SectionHdrTablePtr + 1;
}
uint64_t XCOFFObjectFile::getSectionSize(DataRefImpl Sec) const {
- uint64_t Result = 0;
- llvm_unreachable("Not yet implemented!");
- return Result;
+ return toSection(Sec)->SectionSize;
}
std::error_code XCOFFObjectFile::getSectionContents(DataRefImpl Sec,
@@ -124,21 +162,17 @@ bool XCOFFObjectFile::isSectionCompresse
}
bool XCOFFObjectFile::isSectionText(DataRefImpl Sec) const {
- bool Result = false;
- llvm_unreachable("Not yet implemented!");
- return Result;
+ return toSection(Sec)->Flags & XCOFF::STYP_TEXT;
}
bool XCOFFObjectFile::isSectionData(DataRefImpl Sec) const {
- bool Result = false;
- llvm_unreachable("Not yet implemented!");
- return Result;
+ unsigned Flags = toSection(Sec)->Flags;
+ return Flags & (XCOFF::STYP_DATA | XCOFF::STYP_TDATA);
}
bool XCOFFObjectFile::isSectionBSS(DataRefImpl Sec) const {
- bool Result = false;
- llvm_unreachable("Not yet implemented!");
- return Result;
+ unsigned Flags = toSection(Sec)->Flags;
+ return Flags & (XCOFF::STYP_BSS | XCOFF::STYP_TBSS);
}
bool XCOFFObjectFile::isSectionVirtual(DataRefImpl Sec) const {
@@ -202,13 +236,16 @@ basic_symbol_iterator XCOFFObjectFile::s
}
section_iterator XCOFFObjectFile::section_begin() const {
- llvm_unreachable("Not yet implemented!");
- return section_iterator(SectionRef());
+ DataRefImpl DRI;
+ DRI.p = reinterpret_cast<uintptr_t>(SectionHdrTablePtr);
+ return section_iterator(SectionRef(DRI, this));
}
section_iterator XCOFFObjectFile::section_end() const {
- llvm_unreachable("Not yet implemented!");
- return section_iterator(SectionRef());
+ DataRefImpl DRI;
+ DRI.p =
+ reinterpret_cast<uintptr_t>(SectionHdrTablePtr + getNumberOfSections());
+ return section_iterator(SectionRef(DRI, this));
}
uint8_t XCOFFObjectFile::getBytesInAddress() const {
@@ -218,13 +255,13 @@ uint8_t XCOFFObjectFile::getBytesInAddre
}
StringRef XCOFFObjectFile::getFileFormatName() const {
- llvm_unreachable("Not yet implemented!");
- return "";
+ assert(getFileHeaderSize() == XCOFF32FileHeaderSize);
+ return "aixcoff-rs6000";
}
Triple::ArchType XCOFFObjectFile::getArch() const {
- llvm_unreachable("Not yet implemented!");
- return Triple::UnknownArch;
+ assert(getFileHeaderSize() == XCOFF32FileHeaderSize);
+ return Triple::ppc;
}
SubtargetFeatures XCOFFObjectFile::getFeatures() const {
@@ -238,6 +275,12 @@ bool XCOFFObjectFile::isRelocatableObjec
return Result;
}
+Expected<uint64_t> XCOFFObjectFile::getStartAddress() const {
+ // TODO FIXME Should get from auxiliary_header->o_entry when support for the
+ // auxiliary_header is added.
+ return 0;
+}
+
XCOFFObjectFile::XCOFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
: ObjectFile(Binary::ID_XCOFF32, Object) {
@@ -246,6 +289,17 @@ XCOFFObjectFile::XCOFFObjectFile(MemoryB
if ((EC = getObject(FileHdrPtr, Data, base() + CurPtr)))
return;
+
+ CurPtr += getFileHeaderSize();
+ // TODO FIXME we don't have support for an optional header yet, so just skip
+ // past it.
+ CurPtr += FileHdrPtr->AuxHeaderSize;
+
+ if (getNumberOfSections() != 0) {
+ if ((EC = getObject(SectionHdrTablePtr, Data, base() + CurPtr,
+ getNumberOfSections() * getSectionHeaderSize())))
+ return;
+ }
}
Expected<std::unique_ptr<ObjectFile>>
Added: llvm/trunk/test/tools/llvm-objdump/Inputs/xcoff-long-sec-names.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/xcoff-long-sec-names.o?rev=359244&view=auto
==============================================================================
Binary file - no diff available.
Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/xcoff-long-sec-names.o
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: llvm/trunk/test/tools/llvm-objdump/Inputs/xcoff-section-headers-truncate.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/xcoff-section-headers-truncate.o?rev=359244&view=auto
==============================================================================
Binary file - no diff available.
Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/xcoff-section-headers-truncate.o
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: llvm/trunk/test/tools/llvm-objdump/Inputs/xcoff-section-headers.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/xcoff-section-headers.o?rev=359244&view=auto
==============================================================================
Binary file - no diff available.
Propchange: llvm/trunk/test/tools/llvm-objdump/Inputs/xcoff-section-headers.o
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: llvm/trunk/test/tools/llvm-objdump/xcoff-section-headers.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/xcoff-section-headers.test?rev=359244&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/xcoff-section-headers.test (added)
+++ llvm/trunk/test/tools/llvm-objdump/xcoff-section-headers.test Thu Apr 25 14:36:04 2019
@@ -0,0 +1,43 @@
+# RUN: llvm-objdump --section-headers %p/Inputs/xcoff-section-headers.o | \
+# RUN: FileCheck %s
+
+# RUN: llvm-objdump --section-headers %p/Inputs/xcoff-long-sec-names.o | \
+# RUN: FileCheck --check-prefix=LONG %s
+
+# RUN: not llvm-objdump --section-headers 2>&1 \
+# RUN: %p/Inputs/xcoff-section-headers-truncate.o | FileCheck \
+# RUN: --check-prefix=ERROR %s
+
+# ERROR: The end of the file was unexpectedly encountered
+
+# CHECK: xcoff-section-headers.o: file format aixcoff-rs6000
+# CHECK: Sections:
+# CHECK: Idx Name Size VMA Type
+# CHECK: 1 .text 00000080 0000000000000000 TEXT
+# CHECK: 2 .data 00000024 0000000000000080 DATA
+# CHECK: 3 .bss 00000004 00000000000000a4 BSS
+# CHECK: 4 .tdata 00000008 0000000000000000 DATA
+# CHECK: 5 .tbss 00000004 0000000000000008 BSS
+
+# xcoff-section-headers.o Compiled with IBM XL C/C++ for AIX, V16.1.0
+# test.c:
+# int a;
+# int b = 12345;
+# __thread int c;
+# __thread double d = 3.14159;
+#
+# int func(void) {
+# return a;
+# }
+
+# LONG: xcoff-long-sec-names.o: file format aixcoff-rs6000
+# LONG: Sections:
+# LONG: Idx Name Size VMA Type
+# LONG: 1 .dwarnge 00000004 0000000000000000
+# LONG: 2 .dwpbnms 00000004 0000000000000000
+# LONG: 3 .dwpbtyp 00000004 0000000000000000
+
+# xcoff-long-sec-names.o was generated by assembling the following .s file:
+# .dwsect 0x30000 # .dwpbnms section
+# .dwsect 0x40000 # .dwpbtyp section
+# .dwsect 0x50000 # .dwarnge section
More information about the llvm-commits
mailing list