[haiku-commits] BRANCH xyzzy-github.x86_64 - src/tools build/jam

  • From: xyzzy-github.x86_64 <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 11 Aug 2012 10:49:18 +0200 (CEST)

added 1 changeset to branch 'refs/remotes/xyzzy-github/x86_64'
old head: 8098ef47db1f499e149cd5757798687267813cc2
new head: d384cac4439511a49ec1b0b0c673bbcb324e6fdb

----------------------------------------------------------------------------

d384cac: Support ELF64 in set_haiku_revision.

                                      [ Alex Smith <alex@xxxxxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

Commit:      d384cac4439511a49ec1b0b0c673bbcb324e6fdb

Author:      Alex Smith <alex@xxxxxxxxxxxxxxxx>
Date:        Sat Aug 11 08:17:15 2012 UTC

----------------------------------------------------------------------------

3 files changed, 220 insertions(+), 126 deletions(-)
build/jam/FloppyBootImage        |    7 +-
build/jam/Haiku64Image           |    4 +-
src/tools/set_haiku_revision.cpp |  335 ++++++++++++++++++++++------------

----------------------------------------------------------------------------

diff --git a/build/jam/FloppyBootImage b/build/jam/FloppyBootImage
index 1538fa7..fa713da 100644
--- a/build/jam/FloppyBootImage
+++ b/build/jam/FloppyBootImage
@@ -115,12 +115,7 @@ if $(TARGET_ARCH) = x86_64 {
 }
 
 # kernel
-if $(TARGET_ARCH) = x86_64 {
-       # TODO x86_64: ELF64 support not added to set_haiku_revision.
-       AddFilesToFloppyBootArchive system : kernel_$(TARGET_ARCH) ;
-} else {
-       AddFilesToFloppyBootArchive system : <revisioned>kernel_$(TARGET_ARCH) ;
-}
+AddFilesToFloppyBootArchive system : <revisioned>kernel_$(TARGET_ARCH) ;
 
 # scripts and data files
 
diff --git a/build/jam/Haiku64Image b/build/jam/Haiku64Image
index 2e0d698..1c6e288 100644
--- a/build/jam/Haiku64Image
+++ b/build/jam/Haiku64Image
@@ -45,7 +45,7 @@ SYSTEM_PREFERENCES = Appearance Backgrounds 
<preference>Deskbar FileTypes
 SYSTEM_DEMOS = ;
 
 SYSTEM_LIBS = libbe.so libbnetapi.so libdebug.so libjpeg.so libnetwork.so
-       libpng.so libroot.so libroot-addon-icu.so
+       libpng.so <revisioned>libroot.so libroot-addon-icu.so
        libtextencoding.so libtiff.so libtracker.so libtranslation.so
        libz.so
        $(HAIKU_SHARED_LIBSTDC++) $(HAIKU_SHARED_LIBSUPC++)
@@ -118,7 +118,7 @@ AddDriversToHaikuImage input                : ps2_hid 
usb_hid ;
 AddDriversToHaikuImage net                     : $(SYSTEM_ADD_ONS_DRIVERS_NET) 
;
 
 # kernel
-AddFilesToHaikuImage system : kernel_$(TARGET_ARCH) ;
+AddFilesToHaikuImage system : <revisioned>kernel_$(TARGET_ARCH) ;
 
 # libs
 AddLibrariesToHaikuHybridImage system lib
diff --git a/src/tools/set_haiku_revision.cpp b/src/tools/set_haiku_revision.cpp
index 5022398..acaa697 100644
--- a/src/tools/set_haiku_revision.cpp
+++ b/src/tools/set_haiku_revision.cpp
@@ -39,6 +39,13 @@ typedef uint16_t     Elf32_Half;
 typedef uint32_t       Elf32_Off;
 typedef int32_t                Elf32_Sword;
 typedef uint32_t       Elf32_Word;
+typedef uint64_t       Elf64_Addr;
+typedef uint64_t       Elf64_Off;
+typedef uint16_t       Elf64_Half;
+typedef uint32_t       Elf64_Word;
+typedef int32_t                Elf64_Sword;
+typedef uint64_t       Elf64_Xword;
+typedef int64_t                Elf64_Sxword;
 
 // e_ident indices
 #define EI_MAG0                0
@@ -69,6 +76,23 @@ typedef struct {
        Elf32_Half              e_shstrndx;
 } Elf32_Ehdr;
 
+typedef struct {
+       unsigned char   e_ident[EI_NIDENT];
+       Elf64_Half              e_type;
+       Elf64_Half              e_machine;
+       Elf64_Word              e_version;
+       Elf64_Addr              e_entry;
+       Elf64_Off               e_phoff;
+       Elf64_Off               e_shoff;
+       Elf64_Word              e_flags;
+       Elf64_Half              e_ehsize;
+       Elf64_Half              e_phentsize;
+       Elf64_Half              e_phnum;
+       Elf64_Half              e_shentsize;
+       Elf64_Half              e_shnum;
+       Elf64_Half              e_shstrndx;
+} Elf64_Ehdr;
+
 // e_ident EI_CLASS and EI_DATA values
 #define ELFCLASSNONE   0
 #define ELFCLASS32             1
@@ -89,6 +113,17 @@ typedef struct {
        Elf32_Word      p_align;
 } Elf32_Phdr;
 
+typedef struct {
+       Elf64_Word      p_type;
+       Elf64_Word      p_flags;
+       Elf64_Off       p_offset;
+       Elf64_Addr      p_vaddr;
+       Elf64_Addr      p_paddr;
+       Elf64_Xword     p_filesz;
+       Elf64_Xword     p_memsz;
+       Elf64_Xword     p_align;
+} Elf64_Phdr;
+
 // p_type
 #define PT_NULL                0
 #define PT_LOAD                1
@@ -114,6 +149,19 @@ typedef struct {
        Elf32_Word      sh_entsize;
 } Elf32_Shdr;
 
+typedef struct {
+       Elf64_Word      sh_name;
+       Elf64_Word      sh_type;
+       Elf64_Xword     sh_flags;
+       Elf64_Addr      sh_addr;
+       Elf64_Off       sh_offset;
+       Elf64_Xword     sh_size;
+       Elf64_Word      sh_link;
+       Elf64_Word      sh_info;
+       Elf64_Xword     sh_addralign;
+       Elf64_Xword     sh_entsize;
+} Elf64_Shdr;
+
 // sh_type values
 #define SHT_NULL               0
 #define SHT_PROGBITS   1
@@ -135,7 +183,6 @@ typedef struct {
 // special section indexes
 #define SHN_UNDEF              0
 
-static const uint32_t  kMaxELFHeaderSize       = sizeof(Elf32_Ehdr) + 32;
 static const char              kELFFileMagic[4]        = { 0x7f, 'E', 'L', 'F' 
};
 
 
@@ -168,8 +215,7 @@ print_usage(bool error)
 }
 
 // print_usage_and_exit
-static
-void
+static void
 print_usage_and_exit(bool error)
 {
        print_usage(error);
@@ -262,8 +308,8 @@ private:
 
 struct SectionInfo {
        uint32_t        type;
-       uint32_t        offset;
-       uint32_t        size;
+       off_t           offset;
+       size_t          size;
        const char*     name;
 };
 
@@ -307,82 +353,17 @@ public:
                if (fFileSize < 0)
                        throw Exception("Failed to get the file size.");
 
-               // read ELF header
-               Elf32_Ehdr fileHeader;
-               Read(0, &fileHeader, sizeof(Elf32_Ehdr), "Failed to read ELF 
header.");
-
-               // check data encoding (endianess)
-               switch (fileHeader.e_ident[EI_DATA]) {
-                       case ELFDATA2LSB:
-                               fHostEndianess = (htonl(1) != 1);
-                               break;
-                       case ELFDATA2MSB:
-                               fHostEndianess = (htonl(1) == 1);
-                               break;
-                       default:
-                       case ELFDATANONE:
-                               throw Exception(EIO, "Unsupported ELF data 
encoding.");
-                               break;
-               }
-
-               // get the header values
-               fELFHeaderSize  = GetUInt16(fileHeader.e_ehsize);
-               fSectionHeaderTableOffset = GetUInt32(fileHeader.e_shoff);
-               fSectionHeaderSize      = GetUInt16(fileHeader.e_shentsize);
-               fSectionHeaderCount = GetUInt16(fileHeader.e_shnum);
-               bool hasSectionHeaderTable = (fSectionHeaderTableOffset != 0);
-
-               // check the sanity of the header values
-               // ELF header size
-               if (fELFHeaderSize < sizeof(Elf32_Ehdr) || fELFHeaderSize > 
kMaxELFHeaderSize) {
-                       throw Exception(EIO,
-                               "Invalid ELF header: invalid ELF header size: 
%lu.",
-                               fELFHeaderSize);
-               }
-
-               // section header table offset and entry count/size
-               uint32_t sectionHeaderTableSize = 0;
-               if (hasSectionHeaderTable) {
-                       if (fSectionHeaderTableOffset < fELFHeaderSize
-                               || fSectionHeaderTableOffset > fFileSize) {
-                               throw Exception(EIO, "Invalid ELF header: 
invalid section "
-                                                               "header table 
offset: %lu.",
-                                                               
fSectionHeaderTableOffset);
-                       }
-                       sectionHeaderTableSize = fSectionHeaderSize * 
fSectionHeaderCount;
-                       if (fSectionHeaderSize < sizeof(Elf32_Shdr)
-                               || fSectionHeaderTableOffset + 
sectionHeaderTableSize
-                                               > fFileSize) {
-                               throw Exception(EIO, "Invalid ELF header: 
section header "
-                                                               "table exceeds 
file: %lu.",
-                                                               
fSectionHeaderTableOffset
-                                                                       + 
sectionHeaderTableSize);
-                       }
-
-
-                       // load section header string section
-                       uint16_t sectionHeaderStringSectionIndex
-                               = GetUInt16(fileHeader.e_shstrndx);
-                       if (sectionHeaderStringSectionIndex != SHN_UNDEF) {
-                               if (sectionHeaderStringSectionIndex >= 
fSectionHeaderCount) {
-                                       throw Exception(EIO, "Invalid ELF 
header: invalid section "
-                                                                       "header 
string section index: %lu.",
-                                                                       
sectionHeaderStringSectionIndex);
-                               }
-
-                               // get the section info
-                               SectionInfo info;
-                               if 
(_ReadSectionHeader(sectionHeaderStringSectionIndex,
-                                               info)) {
-                                       fSectionHeaderStrings = new 
char[info.size + 1];
-                                       Read(info.offset, 
fSectionHeaderStrings, info.size,
-                                               "Failed to read section header 
string section.");
-                                       fSectionHeaderStringsLength = info.size;
-                                       // null-terminate to be on the safe side
-                                       fSectionHeaderStrings[info.size] = '\0';
-                               }
-                       }
-               }
+               // Read identification information
+               unsigned char ident[EI_NIDENT];
+               Read(0, ident, sizeof(ident), "Failed to read ELF 
identification.");
+               if (memcmp(ident, kELFFileMagic, sizeof(kELFFileMagic)) != 0)
+                       throw Exception("Not a valid ELF file.");
+               fELFClass = ident[EI_CLASS];
+
+               if (fELFClass == ELFCLASS64)
+                       _ParseELFHeader<Elf64_Ehdr, Elf64_Shdr>();
+               else
+                       _ParseELFHeader<Elf32_Ehdr, Elf32_Shdr>();
        }
 
        bool FindSectionByName(const char* name, SectionInfo& foundInfo)
@@ -392,9 +373,16 @@ public:
                        return false;
 
                // iterate through the section headers
-               for (int32_t i = 0; i < (int32_t)fSectionHeaderCount; i++) {
+               for (size_t i = 0; i < fSectionHeaderCount; i++) {
                        SectionInfo info;
-                       if (_ReadSectionHeader(i, info)) {
+
+                       bool result;
+                       if (fELFClass == ELFCLASS64)
+                               result = _ReadSectionHeader<Elf64_Shdr>(i, 
info);
+                       else
+                               result = _ReadSectionHeader<Elf32_Shdr>(i, 
info);
+
+                       if (result) {
 //printf("section %3d: offset: %7d, size: %7d, name: %s\n", i, info.offset, 
info.size, info.name);
                                if (strcmp(info.name, name) == 0) {
                                        foundInfo = info;
@@ -457,44 +445,105 @@ public:
                return lseek(fFD, currentPos, SEEK_SET);
        }
 
-       // GetInt16
-       int16_t GetInt16(int16_t value)
-       {
-               return (fHostEndianess ? value : _SwapUInt16(value));
-       }
+       template<typename Type>
+       Type GetValue(Type& value);
 
-       // GetUInt16
-       uint16_t GetUInt16(uint16_t value)
+private:
+       template<typename EhdrType, typename ShdrType>
+       void _ParseELFHeader()
        {
-               return (fHostEndianess ? value : _SwapUInt16(value));
-       }
+               // read ELF header
+               EhdrType fileHeader;
+               Read(0, &fileHeader, sizeof(EhdrType), "Failed to read ELF 
header.");
 
-       // GetInt32
-       int32_t GetInt32(int32_t value)
-       {
-               return (fHostEndianess ? value : _SwapUInt32(value));
-       }
+               // check data encoding (endianess)
+               switch (fileHeader.e_ident[EI_DATA]) {
+                       case ELFDATA2LSB:
+                               fHostEndianess = (htonl(1) != 1);
+                               break;
+                       case ELFDATA2MSB:
+                               fHostEndianess = (htonl(1) == 1);
+                               break;
+                       default:
+                       case ELFDATANONE:
+                               throw Exception(EIO, "Unsupported ELF data 
encoding.");
+                               break;
+               }
 
-       // GetUInt32
-       uint32_t GetUInt32(uint32_t value)
-       {
-               return (fHostEndianess ? value : _SwapUInt32(value));
+               // get the header values
+               fELFHeaderSize  = GetValue(fileHeader.e_ehsize);
+               fSectionHeaderTableOffset = GetValue(fileHeader.e_shoff);
+               fSectionHeaderSize      = GetValue(fileHeader.e_shentsize);
+               fSectionHeaderCount = GetValue(fileHeader.e_shnum);
+               bool hasSectionHeaderTable = (fSectionHeaderTableOffset != 0);
+
+               // check the sanity of the header values
+               // ELF header size
+               if (fELFHeaderSize < sizeof(EhdrType)) {
+                       throw Exception(EIO,
+                               "Invalid ELF header: invalid ELF header size: 
%lu.",
+                               fELFHeaderSize);
+               }
+
+               // section header table offset and entry count/size
+               if (hasSectionHeaderTable) {
+                       if (fSectionHeaderTableOffset < (off_t)fELFHeaderSize
+                               || fSectionHeaderTableOffset > fFileSize) {
+                               throw Exception(EIO, "Invalid ELF header: 
invalid section "
+                                                               "header table 
offset: %llu.",
+                                                               
fSectionHeaderTableOffset);
+                       }
+                       size_t sectionHeaderTableSize
+                               = fSectionHeaderSize * fSectionHeaderCount;
+                       if (fSectionHeaderSize < (off_t)sizeof(ShdrType)
+                               || fSectionHeaderTableOffset + 
(off_t)sectionHeaderTableSize
+                                       > fFileSize) {
+                               throw Exception(EIO, "Invalid ELF header: 
section header "
+                                                               "table exceeds 
file: %llu.",
+                                                               
fSectionHeaderTableOffset
+                                                                       + 
sectionHeaderTableSize);
+                       }
+
+
+                       // load section header string section
+                       uint16_t sectionHeaderStringSectionIndex
+                               = GetValue(fileHeader.e_shstrndx);
+                       if (sectionHeaderStringSectionIndex != SHN_UNDEF) {
+                               if (sectionHeaderStringSectionIndex >= 
fSectionHeaderCount) {
+                                       throw Exception(EIO, "Invalid ELF 
header: invalid section "
+                                                                       "header 
string section index: %u.",
+                                                                       
sectionHeaderStringSectionIndex);
+                               }
+
+                               // get the section info
+                               SectionInfo info;
+                               if 
(_ReadSectionHeader<ShdrType>(sectionHeaderStringSectionIndex,
+                                               info)) {
+                                       fSectionHeaderStrings = new 
char[info.size + 1];
+                                       Read(info.offset, 
fSectionHeaderStrings, info.size,
+                                               "Failed to read section header 
string section.");
+                                       fSectionHeaderStringsLength = info.size;
+                                       // null-terminate to be on the safe side
+                                       fSectionHeaderStrings[info.size] = '\0';
+                               }
+                       }
+               }
        }
 
-private:
+       template<typename ShdrType>
        bool _ReadSectionHeader(int index, SectionInfo& info)
        {
-               uint32_t shOffset = fSectionHeaderTableOffset
+               off_t shOffset = fSectionHeaderTableOffset
                        + index * fSectionHeaderSize;
-               Elf32_Shdr sectionHeader;
-               Read(shOffset, &sectionHeader, sizeof(Elf32_Shdr),
+               ShdrType sectionHeader;
+               Read(shOffset, &sectionHeader, sizeof(ShdrType),
                        "Failed to read ELF section header.");
 
                // get the header values
-               uint32_t type           = GetUInt32(sectionHeader.sh_type);
-               uint32_t offset         = GetUInt32(sectionHeader.sh_offset);
-               uint32_t size           = GetUInt32(sectionHeader.sh_size);
-               uint32_t nameIndex      = GetUInt32(sectionHeader.sh_name);
+               uint32_t type           = GetValue(sectionHeader.sh_type);
+               off_t offset            = GetValue(sectionHeader.sh_offset);
+               size_t size                     = 
GetValue(sectionHeader.sh_size);
+               uint32_t nameIndex      = GetValue(sectionHeader.sh_name);
 
                // check the values
                // SHT_NULL marks the header unused,
@@ -503,14 +552,14 @@ private:
 
                // SHT_NOBITS sections take no space in the file
                if (type != SHT_NOBITS) {
-                       if (offset < fELFHeaderSize || offset > fFileSize) {
+                       if (offset < (off_t)fELFHeaderSize || offset > 
fFileSize) {
                                throw Exception(EIO, "Invalid ELF section 
header: "
-                                                               "invalid 
section offset: %lu.", offset);
+                                                               "invalid 
section offset: %llu.", offset);
                        }
-                       uint32_t sectionEnd = offset + size;
+                       off_t sectionEnd = offset + size;
                        if (sectionEnd > fFileSize) {
                                throw Exception(EIO, "Invalid ELF section 
header: "
-                                                               "section 
exceeds file: %lu.", sectionEnd);
+                                                               "section 
exceeds file: %llu.", sectionEnd);
                        }
                }
 
@@ -546,19 +595,69 @@ private:
                        | _SwapUInt16(uint16_t(value >> 16));
        }
 
+       // _SwapUInt64
+       static inline uint64_t _SwapUInt64(uint64_t value)
+       {
+               return ((uint64_t)_SwapUInt32(value & 0xffffffff) << 32)
+                       | _SwapUInt32(uint32_t(value >> 32));
+       }
+
 private:
        int                     fFD;
+       uint8_t         fELFClass;
        bool            fHostEndianess;
        off_t           fFileSize;
-       uint32_t        fELFHeaderSize;
-       uint32_t        fSectionHeaderTableOffset;
-       uint32_t        fSectionHeaderSize;
-       uint32_t        fSectionHeaderCount;
+       size_t          fELFHeaderSize;
+       off_t           fSectionHeaderTableOffset;
+       size_t          fSectionHeaderSize;
+       size_t          fSectionHeaderCount;
        char*           fSectionHeaderStrings;
-       int                     fSectionHeaderStringsLength;
+       uint32_t        fSectionHeaderStringsLength;
 };
 
 
+template<>
+int16_t ELFObject::GetValue(int16_t& value)
+{
+       return (fHostEndianess ? value : _SwapUInt16(value));
+}
+
+
+template<>
+uint16_t ELFObject::GetValue(uint16_t& value)
+{
+       return (fHostEndianess ? value : _SwapUInt16(value));
+}
+
+
+template<>
+int32_t ELFObject::GetValue(int32_t& value)
+{
+       return (fHostEndianess ? value : _SwapUInt32(value));
+}
+
+
+template<>
+uint32_t ELFObject::GetValue(uint32_t& value)
+{
+       return (fHostEndianess ? value : _SwapUInt32(value));
+}
+
+
+template<>
+int64_t ELFObject::GetValue(int64_t& value)
+{
+       return (fHostEndianess ? value : _SwapUInt64(value));
+}
+
+
+template<>
+uint64_t ELFObject::GetValue(uint64_t& value)
+{
+       return (fHostEndianess ? value : _SwapUInt64(value));
+}
+
+
 // main
 int
 main(int argc, const char* const* argv)


Other related posts:

  • » [haiku-commits] BRANCH xyzzy-github.x86_64 - src/tools build/jam - xyzzy-github . x86_64